aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-12-12 06:42:12 -0500
committerJens Axboe <axboe@kernel.dk>2011-12-12 06:42:12 -0500
commitb302545744c031eae04a43fb1c56cc17e00a193a (patch)
tree6d72f21f033d5e2e1589dada45b767a0327e45d0 /drivers/block
parentdfaf3c036cd46a73f4ef3e4b75c1f647e503d4e1 (diff)
block/swim3: Locking fixes
The old PowerMac swim3 driver has some "interesting" locking issues, using a private lock and failing to lock the queue before completing requests, which triggered WARN_ONs among others. This rips out the private lock, makes everything operate under the block queue lock, and generally makes things simpler. We used to also share a queue between the two possible instances which was problematic since we might pick the wrong controller in some cases, so make the queue and the current request per-instance and use queuedata to point to our private data which is a lot cleaner. We still share the queue lock but then, it's nearly impossible to actually use 2 swim3's simultaneously: one would need to have a Wallstreet PowerBook, the only machine afaik with two of these on the motherboard, and populate both hotswap bays with a floppy drive (the machine ships only with one), so nobody cares... While at it, add a little fix to clear up stale interrupts when loading the driver or plugging a floppy drive in a bay. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/swim3.c362
1 files changed, 215 insertions, 147 deletions
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index ae3e167e17a..89ddab127e3 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -16,6 +16,8 @@
16 * handle GCR disks 16 * handle GCR disks
17 */ 17 */
18 18
19#undef DEBUG
20
19#include <linux/stddef.h> 21#include <linux/stddef.h>
20#include <linux/kernel.h> 22#include <linux/kernel.h>
21#include <linux/sched.h> 23#include <linux/sched.h>
@@ -36,13 +38,11 @@
36#include <asm/machdep.h> 38#include <asm/machdep.h>
37#include <asm/pmac_feature.h> 39#include <asm/pmac_feature.h>
38 40
39static DEFINE_MUTEX(swim3_mutex);
40static struct request_queue *swim3_queue;
41static struct gendisk *disks[2];
42static struct request *fd_req;
43
44#define MAX_FLOPPIES 2 41#define MAX_FLOPPIES 2
45 42
43static DEFINE_MUTEX(swim3_mutex);
44static struct gendisk *disks[MAX_FLOPPIES];
45
46enum swim_state { 46enum swim_state {
47 idle, 47 idle,
48 locating, 48 locating,
@@ -177,7 +177,6 @@ struct swim3 {
177 177
178struct floppy_state { 178struct floppy_state {
179 enum swim_state state; 179 enum swim_state state;
180 spinlock_t lock;
181 struct swim3 __iomem *swim3; /* hardware registers */ 180 struct swim3 __iomem *swim3; /* hardware registers */
182 struct dbdma_regs __iomem *dma; /* DMA controller registers */ 181 struct dbdma_regs __iomem *dma; /* DMA controller registers */
183 int swim3_intr; /* interrupt number for SWIM3 */ 182 int swim3_intr; /* interrupt number for SWIM3 */
@@ -204,8 +203,20 @@ struct floppy_state {
204 int wanted; 203 int wanted;
205 struct macio_dev *mdev; 204 struct macio_dev *mdev;
206 char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)]; 205 char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)];
206 int index;
207 struct request *cur_req;
207}; 208};
208 209
210#define swim3_err(fmt, arg...) dev_err(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg)
211#define swim3_warn(fmt, arg...) dev_warn(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg)
212#define swim3_info(fmt, arg...) dev_info(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg)
213
214#ifdef DEBUG
215#define swim3_dbg(fmt, arg...) dev_dbg(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg)
216#else
217#define swim3_dbg(fmt, arg...) do { } while(0)
218#endif
219
209static struct floppy_state floppy_states[MAX_FLOPPIES]; 220static struct floppy_state floppy_states[MAX_FLOPPIES];
210static int floppy_count = 0; 221static int floppy_count = 0;
211static DEFINE_SPINLOCK(swim3_lock); 222static DEFINE_SPINLOCK(swim3_lock);
@@ -224,17 +235,8 @@ static unsigned short write_postamble[] = {
224 0, 0, 0, 0, 0, 0 235 0, 0, 0, 0, 0, 0
225}; 236};
226 237
227static void swim3_select(struct floppy_state *fs, int sel);
228static void swim3_action(struct floppy_state *fs, int action);
229static int swim3_readbit(struct floppy_state *fs, int bit);
230static void do_fd_request(struct request_queue * q);
231static void start_request(struct floppy_state *fs);
232static void set_timeout(struct floppy_state *fs, int nticks,
233 void (*proc)(unsigned long));
234static void scan_track(struct floppy_state *fs);
235static void seek_track(struct floppy_state *fs, int n); 238static void seek_track(struct floppy_state *fs, int n);
236static void init_dma(struct dbdma_cmd *cp, int cmd, void *buf, int count); 239static void init_dma(struct dbdma_cmd *cp, int cmd, void *buf, int count);
237static void setup_transfer(struct floppy_state *fs);
238static void act(struct floppy_state *fs); 240static void act(struct floppy_state *fs);
239static void scan_timeout(unsigned long data); 241static void scan_timeout(unsigned long data);
240static void seek_timeout(unsigned long data); 242static void seek_timeout(unsigned long data);
@@ -254,18 +256,21 @@ static unsigned int floppy_check_events(struct gendisk *disk,
254 unsigned int clearing); 256 unsigned int clearing);
255static int floppy_revalidate(struct gendisk *disk); 257static int floppy_revalidate(struct gendisk *disk);
256 258
257static bool swim3_end_request(int err, unsigned int nr_bytes) 259static bool swim3_end_request(struct floppy_state *fs, int err, unsigned int nr_bytes)
258{ 260{
259 if (__blk_end_request(fd_req, err, nr_bytes)) 261 struct request *req = fs->cur_req;
260 return true; 262 int rc;
261 263
262 fd_req = NULL; 264 swim3_dbg(" end request, err=%d nr_bytes=%d, cur_req=%p\n",
263 return false; 265 err, nr_bytes, req);
264}
265 266
266static bool swim3_end_request_cur(int err) 267 if (err)
267{ 268 nr_bytes = blk_rq_cur_bytes(req);
268 return swim3_end_request(err, blk_rq_cur_bytes(fd_req)); 269 rc = __blk_end_request(req, err, nr_bytes);
270 if (rc)
271 return true;
272 fs->cur_req = NULL;
273 return false;
269} 274}
270 275
271static void swim3_select(struct floppy_state *fs, int sel) 276static void swim3_select(struct floppy_state *fs, int sel)
@@ -303,50 +308,53 @@ static int swim3_readbit(struct floppy_state *fs, int bit)
303 return (stat & DATA) == 0; 308 return (stat & DATA) == 0;
304} 309}
305 310
306static void do_fd_request(struct request_queue * q)
307{
308 int i;
309
310 for(i=0; i<floppy_count; i++) {
311 struct floppy_state *fs = &floppy_states[i];
312 if (fs->mdev->media_bay &&
313 check_media_bay(fs->mdev->media_bay) != MB_FD)
314 continue;
315 start_request(fs);
316 }
317}
318
319static void start_request(struct floppy_state *fs) 311static void start_request(struct floppy_state *fs)
320{ 312{
321 struct request *req; 313 struct request *req;
322 unsigned long x; 314 unsigned long x;
323 315
316 swim3_dbg("start request, initial state=%d\n", fs->state);
317
324 if (fs->state == idle && fs->wanted) { 318 if (fs->state == idle && fs->wanted) {
325 fs->state = available; 319 fs->state = available;
326 wake_up(&fs->wait); 320 wake_up(&fs->wait);
327 return; 321 return;
328 } 322 }
329 while (fs->state == idle) { 323 while (fs->state == idle) {
330 if (!fd_req) { 324 swim3_dbg("start request, idle loop, cur_req=%p\n", fs->cur_req);
331 fd_req = blk_fetch_request(swim3_queue); 325 if (!fs->cur_req) {
332 if (!fd_req) 326 fs->cur_req = blk_fetch_request(disks[fs->index]->queue);
327 swim3_dbg(" fetched request %p\n", fs->cur_req);
328 if (!fs->cur_req)
333 break; 329 break;
334 } 330 }
335 req = fd_req; 331 req = fs->cur_req;
336#if 0 332
337 printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%u buf=%p\n", 333 if (fs->mdev->media_bay &&
338 req->rq_disk->disk_name, req->cmd, 334 check_media_bay(fs->mdev->media_bay) != MB_FD) {
339 (long)blk_rq_pos(req), blk_rq_sectors(req), req->buffer); 335 swim3_dbg("%s", " media bay absent, dropping req\n");
340 printk(" errors=%d current_nr_sectors=%u\n", 336 swim3_end_request(fs, -ENODEV, 0);
341 req->errors, blk_rq_cur_sectors(req)); 337 continue;
338 }
339
340#if 0 /* This is really too verbose */
341 swim3_dbg("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%u buf=%p\n",
342 req->rq_disk->disk_name, req->cmd,
343 (long)blk_rq_pos(req), blk_rq_sectors(req),
344 req->buffer);
345 swim3_dbg(" errors=%d current_nr_sectors=%u\n",
346 req->errors, blk_rq_cur_sectors(req));
342#endif 347#endif
343 348
344 if (blk_rq_pos(req) >= fs->total_secs) { 349 if (blk_rq_pos(req) >= fs->total_secs) {
345 swim3_end_request_cur(-EIO); 350 swim3_dbg(" pos out of bounds (%ld, max is %ld)\n",
351 (long)blk_rq_pos(req), (long)fs->total_secs);
352 swim3_end_request(fs, -EIO, 0);
346 continue; 353 continue;
347 } 354 }
348 if (fs->ejected) { 355 if (fs->ejected) {
349 swim3_end_request_cur(-EIO); 356 swim3_dbg("%s", " disk ejected\n");
357 swim3_end_request(fs, -EIO, 0);
350 continue; 358 continue;
351 } 359 }
352 360
@@ -354,7 +362,8 @@ static void start_request(struct floppy_state *fs)
354 if (fs->write_prot < 0) 362 if (fs->write_prot < 0)
355 fs->write_prot = swim3_readbit(fs, WRITE_PROT); 363 fs->write_prot = swim3_readbit(fs, WRITE_PROT);
356 if (fs->write_prot) { 364 if (fs->write_prot) {
357 swim3_end_request_cur(-EIO); 365 swim3_dbg("%s", " try to write, disk write protected\n");
366 swim3_end_request(fs, -EIO, 0);
358 continue; 367 continue;
359 } 368 }
360 } 369 }
@@ -369,7 +378,6 @@ static void start_request(struct floppy_state *fs)
369 x = ((long)blk_rq_pos(req)) % fs->secpercyl; 378 x = ((long)blk_rq_pos(req)) % fs->secpercyl;
370 fs->head = x / fs->secpertrack; 379 fs->head = x / fs->secpertrack;
371 fs->req_sector = x % fs->secpertrack + 1; 380 fs->req_sector = x % fs->secpertrack + 1;
372 fd_req = req;
373 fs->state = do_transfer; 381 fs->state = do_transfer;
374 fs->retries = 0; 382 fs->retries = 0;
375 383
@@ -377,12 +385,14 @@ static void start_request(struct floppy_state *fs)
377 } 385 }
378} 386}
379 387
388static void do_fd_request(struct request_queue * q)
389{
390 start_request(q->queuedata);
391}
392
380static void set_timeout(struct floppy_state *fs, int nticks, 393static void set_timeout(struct floppy_state *fs, int nticks,
381 void (*proc)(unsigned long)) 394 void (*proc)(unsigned long))
382{ 395{
383 unsigned long flags;
384
385 spin_lock_irqsave(&fs->lock, flags);
386 if (fs->timeout_pending) 396 if (fs->timeout_pending)
387 del_timer(&fs->timeout); 397 del_timer(&fs->timeout);
388 fs->timeout.expires = jiffies + nticks; 398 fs->timeout.expires = jiffies + nticks;
@@ -390,7 +400,6 @@ static void set_timeout(struct floppy_state *fs, int nticks,
390 fs->timeout.data = (unsigned long) fs; 400 fs->timeout.data = (unsigned long) fs;
391 add_timer(&fs->timeout); 401 add_timer(&fs->timeout);
392 fs->timeout_pending = 1; 402 fs->timeout_pending = 1;
393 spin_unlock_irqrestore(&fs->lock, flags);
394} 403}
395 404
396static inline void scan_track(struct floppy_state *fs) 405static inline void scan_track(struct floppy_state *fs)
@@ -442,40 +451,45 @@ static inline void setup_transfer(struct floppy_state *fs)
442 struct swim3 __iomem *sw = fs->swim3; 451 struct swim3 __iomem *sw = fs->swim3;
443 struct dbdma_cmd *cp = fs->dma_cmd; 452 struct dbdma_cmd *cp = fs->dma_cmd;
444 struct dbdma_regs __iomem *dr = fs->dma; 453 struct dbdma_regs __iomem *dr = fs->dma;
454 struct request *req = fs->cur_req;
445 455
446 if (blk_rq_cur_sectors(fd_req) <= 0) { 456 if (blk_rq_cur_sectors(req) <= 0) {
447 printk(KERN_ERR "swim3: transfer 0 sectors?\n"); 457 swim3_warn("%s", "Transfer 0 sectors ?\n");
448 return; 458 return;
449 } 459 }
450 if (rq_data_dir(fd_req) == WRITE) 460 if (rq_data_dir(req) == WRITE)
451 n = 1; 461 n = 1;
452 else { 462 else {
453 n = fs->secpertrack - fs->req_sector + 1; 463 n = fs->secpertrack - fs->req_sector + 1;
454 if (n > blk_rq_cur_sectors(fd_req)) 464 if (n > blk_rq_cur_sectors(req))
455 n = blk_rq_cur_sectors(fd_req); 465 n = blk_rq_cur_sectors(req);
456 } 466 }
467
468 swim3_dbg(" setup xfer at sect %d (of %d) head %d for %d\n",
469 fs->req_sector, fs->secpertrack, fs->head, n);
470
457 fs->scount = n; 471 fs->scount = n;
458 swim3_select(fs, fs->head? READ_DATA_1: READ_DATA_0); 472 swim3_select(fs, fs->head? READ_DATA_1: READ_DATA_0);
459 out_8(&sw->sector, fs->req_sector); 473 out_8(&sw->sector, fs->req_sector);
460 out_8(&sw->nsect, n); 474 out_8(&sw->nsect, n);
461 out_8(&sw->gap3, 0); 475 out_8(&sw->gap3, 0);
462 out_le32(&dr->cmdptr, virt_to_bus(cp)); 476 out_le32(&dr->cmdptr, virt_to_bus(cp));
463 if (rq_data_dir(fd_req) == WRITE) { 477 if (rq_data_dir(req) == WRITE) {
464 /* Set up 3 dma commands: write preamble, data, postamble */ 478 /* Set up 3 dma commands: write preamble, data, postamble */
465 init_dma(cp, OUTPUT_MORE, write_preamble, sizeof(write_preamble)); 479 init_dma(cp, OUTPUT_MORE, write_preamble, sizeof(write_preamble));
466 ++cp; 480 ++cp;
467 init_dma(cp, OUTPUT_MORE, fd_req->buffer, 512); 481 init_dma(cp, OUTPUT_MORE, req->buffer, 512);
468 ++cp; 482 ++cp;
469 init_dma(cp, OUTPUT_LAST, write_postamble, sizeof(write_postamble)); 483 init_dma(cp, OUTPUT_LAST, write_postamble, sizeof(write_postamble));
470 } else { 484 } else {
471 init_dma(cp, INPUT_LAST, fd_req->buffer, n * 512); 485 init_dma(cp, INPUT_LAST, req->buffer, n * 512);
472 } 486 }
473 ++cp; 487 ++cp;
474 out_le16(&cp->command, DBDMA_STOP); 488 out_le16(&cp->command, DBDMA_STOP);
475 out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); 489 out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
476 in_8(&sw->error); 490 in_8(&sw->error);
477 out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); 491 out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
478 if (rq_data_dir(fd_req) == WRITE) 492 if (rq_data_dir(req) == WRITE)
479 out_8(&sw->control_bis, WRITE_SECTORS); 493 out_8(&sw->control_bis, WRITE_SECTORS);
480 in_8(&sw->intr); 494 in_8(&sw->intr);
481 out_le32(&dr->control, (RUN << 16) | RUN); 495 out_le32(&dr->control, (RUN << 16) | RUN);
@@ -488,12 +502,16 @@ static inline void setup_transfer(struct floppy_state *fs)
488static void act(struct floppy_state *fs) 502static void act(struct floppy_state *fs)
489{ 503{
490 for (;;) { 504 for (;;) {
505 swim3_dbg(" act loop, state=%d, req_cyl=%d, cur_cyl=%d\n",
506 fs->state, fs->req_cyl, fs->cur_cyl);
507
491 switch (fs->state) { 508 switch (fs->state) {
492 case idle: 509 case idle:
493 return; /* XXX shouldn't get here */ 510 return; /* XXX shouldn't get here */
494 511
495 case locating: 512 case locating:
496 if (swim3_readbit(fs, TRACK_ZERO)) { 513 if (swim3_readbit(fs, TRACK_ZERO)) {
514 swim3_dbg("%s", " locate track 0\n");
497 fs->cur_cyl = 0; 515 fs->cur_cyl = 0;
498 if (fs->req_cyl == 0) 516 if (fs->req_cyl == 0)
499 fs->state = do_transfer; 517 fs->state = do_transfer;
@@ -511,7 +529,7 @@ static void act(struct floppy_state *fs)
511 break; 529 break;
512 } 530 }
513 if (fs->req_cyl == fs->cur_cyl) { 531 if (fs->req_cyl == fs->cur_cyl) {
514 printk("whoops, seeking 0\n"); 532 swim3_warn("%s", "Whoops, seeking 0\n");
515 fs->state = do_transfer; 533 fs->state = do_transfer;
516 break; 534 break;
517 } 535 }
@@ -527,7 +545,9 @@ static void act(struct floppy_state *fs)
527 case do_transfer: 545 case do_transfer:
528 if (fs->cur_cyl != fs->req_cyl) { 546 if (fs->cur_cyl != fs->req_cyl) {
529 if (fs->retries > 5) { 547 if (fs->retries > 5) {
530 swim3_end_request_cur(-EIO); 548 swim3_err("Wrong cylinder in transfer, want: %d got %d\n",
549 fs->req_cyl, fs->cur_cyl);
550 swim3_end_request(fs, -EIO, 0);
531 fs->state = idle; 551 fs->state = idle;
532 return; 552 return;
533 } 553 }
@@ -542,7 +562,7 @@ static void act(struct floppy_state *fs)
542 return; 562 return;
543 563
544 default: 564 default:
545 printk(KERN_ERR"swim3: unknown state %d\n", fs->state); 565 swim3_err("Unknown state %d\n", fs->state);
546 return; 566 return;
547 } 567 }
548 } 568 }
@@ -552,59 +572,75 @@ static void scan_timeout(unsigned long data)
552{ 572{
553 struct floppy_state *fs = (struct floppy_state *) data; 573 struct floppy_state *fs = (struct floppy_state *) data;
554 struct swim3 __iomem *sw = fs->swim3; 574 struct swim3 __iomem *sw = fs->swim3;
575 unsigned long flags;
576
577 swim3_dbg("* scan timeout, state=%d\n", fs->state);
555 578
579 spin_lock_irqsave(&swim3_lock, flags);
556 fs->timeout_pending = 0; 580 fs->timeout_pending = 0;
557 out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); 581 out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
558 out_8(&sw->select, RELAX); 582 out_8(&sw->select, RELAX);
559 out_8(&sw->intr_enable, 0); 583 out_8(&sw->intr_enable, 0);
560 fs->cur_cyl = -1; 584 fs->cur_cyl = -1;
561 if (fs->retries > 5) { 585 if (fs->retries > 5) {
562 swim3_end_request_cur(-EIO); 586 swim3_end_request(fs, -EIO, 0);
563 fs->state = idle; 587 fs->state = idle;
564 start_request(fs); 588 start_request(fs);
565 } else { 589 } else {
566 fs->state = jogging; 590 fs->state = jogging;
567 act(fs); 591 act(fs);
568 } 592 }
593 spin_unlock_irqrestore(&swim3_lock, flags);
569} 594}
570 595
571static void seek_timeout(unsigned long data) 596static void seek_timeout(unsigned long data)
572{ 597{
573 struct floppy_state *fs = (struct floppy_state *) data; 598 struct floppy_state *fs = (struct floppy_state *) data;
574 struct swim3 __iomem *sw = fs->swim3; 599 struct swim3 __iomem *sw = fs->swim3;
600 unsigned long flags;
601
602 swim3_dbg("* seek timeout, state=%d\n", fs->state);
575 603
604 spin_lock_irqsave(&swim3_lock, flags);
576 fs->timeout_pending = 0; 605 fs->timeout_pending = 0;
577 out_8(&sw->control_bic, DO_SEEK); 606 out_8(&sw->control_bic, DO_SEEK);
578 out_8(&sw->select, RELAX); 607 out_8(&sw->select, RELAX);
579 out_8(&sw->intr_enable, 0); 608 out_8(&sw->intr_enable, 0);
580 printk(KERN_ERR "swim3: seek timeout\n"); 609 swim3_err("%s", "Seek timeout\n");
581 swim3_end_request_cur(-EIO); 610 swim3_end_request(fs, -EIO, 0);
582 fs->state = idle; 611 fs->state = idle;
583 start_request(fs); 612 start_request(fs);
613 spin_unlock_irqrestore(&swim3_lock, flags);
584} 614}
585 615
586static void settle_timeout(unsigned long data) 616static void settle_timeout(unsigned long data)
587{ 617{
588 struct floppy_state *fs = (struct floppy_state *) data; 618 struct floppy_state *fs = (struct floppy_state *) data;
589 struct swim3 __iomem *sw = fs->swim3; 619 struct swim3 __iomem *sw = fs->swim3;
620 unsigned long flags;
621
622 swim3_dbg("* settle timeout, state=%d\n", fs->state);
590 623
624 spin_lock_irqsave(&swim3_lock, flags);
591 fs->timeout_pending = 0; 625 fs->timeout_pending = 0;
592 if (swim3_readbit(fs, SEEK_COMPLETE)) { 626 if (swim3_readbit(fs, SEEK_COMPLETE)) {
593 out_8(&sw->select, RELAX); 627 out_8(&sw->select, RELAX);
594 fs->state = locating; 628 fs->state = locating;
595 act(fs); 629 act(fs);
596 return; 630 goto unlock;
597 } 631 }
598 out_8(&sw->select, RELAX); 632 out_8(&sw->select, RELAX);
599 if (fs->settle_time < 2*HZ) { 633 if (fs->settle_time < 2*HZ) {
600 ++fs->settle_time; 634 ++fs->settle_time;
601 set_timeout(fs, 1, settle_timeout); 635 set_timeout(fs, 1, settle_timeout);
602 return; 636 goto unlock;
603 } 637 }
604 printk(KERN_ERR "swim3: seek settle timeout\n"); 638 swim3_err("%s", "Seek settle timeout\n");
605 swim3_end_request_cur(-EIO); 639 swim3_end_request(fs, -EIO, 0);
606 fs->state = idle; 640 fs->state = idle;
607 start_request(fs); 641 start_request(fs);
642 unlock:
643 spin_unlock_irqrestore(&swim3_lock, flags);
608} 644}
609 645
610static void xfer_timeout(unsigned long data) 646static void xfer_timeout(unsigned long data)
@@ -612,8 +648,12 @@ static void xfer_timeout(unsigned long data)
612 struct floppy_state *fs = (struct floppy_state *) data; 648 struct floppy_state *fs = (struct floppy_state *) data;
613 struct swim3 __iomem *sw = fs->swim3; 649 struct swim3 __iomem *sw = fs->swim3;
614 struct dbdma_regs __iomem *dr = fs->dma; 650 struct dbdma_regs __iomem *dr = fs->dma;
651 unsigned long flags;
615 int n; 652 int n;
616 653
654 swim3_dbg("* xfer timeout, state=%d\n", fs->state);
655
656 spin_lock_irqsave(&swim3_lock, flags);
617 fs->timeout_pending = 0; 657 fs->timeout_pending = 0;
618 out_le32(&dr->control, RUN << 16); 658 out_le32(&dr->control, RUN << 16);
619 /* We must wait a bit for dbdma to stop */ 659 /* We must wait a bit for dbdma to stop */
@@ -622,12 +662,13 @@ static void xfer_timeout(unsigned long data)
622 out_8(&sw->intr_enable, 0); 662 out_8(&sw->intr_enable, 0);
623 out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION); 663 out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
624 out_8(&sw->select, RELAX); 664 out_8(&sw->select, RELAX);
625 printk(KERN_ERR "swim3: timeout %sing sector %ld\n", 665 swim3_err("Timeout %sing sector %ld\n",
626 (rq_data_dir(fd_req)==WRITE? "writ": "read"), 666 (rq_data_dir(fs->cur_req)==WRITE? "writ": "read"),
627 (long)blk_rq_pos(fd_req)); 667 (long)blk_rq_pos(fs->cur_req));
628 swim3_end_request_cur(-EIO); 668 swim3_end_request(fs, -EIO, 0);
629 fs->state = idle; 669 fs->state = idle;
630 start_request(fs); 670 start_request(fs);
671 spin_unlock_irqrestore(&swim3_lock, flags);
631} 672}
632 673
633static irqreturn_t swim3_interrupt(int irq, void *dev_id) 674static irqreturn_t swim3_interrupt(int irq, void *dev_id)
@@ -638,12 +679,17 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
638 int stat, resid; 679 int stat, resid;
639 struct dbdma_regs __iomem *dr; 680 struct dbdma_regs __iomem *dr;
640 struct dbdma_cmd *cp; 681 struct dbdma_cmd *cp;
682 unsigned long flags;
683 struct request *req = fs->cur_req;
684
685 swim3_dbg("* interrupt, state=%d\n", fs->state);
641 686
687 spin_lock_irqsave(&swim3_lock, flags);
642 intr = in_8(&sw->intr); 688 intr = in_8(&sw->intr);
643 err = (intr & ERROR_INTR)? in_8(&sw->error): 0; 689 err = (intr & ERROR_INTR)? in_8(&sw->error): 0;
644 if ((intr & ERROR_INTR) && fs->state != do_transfer) 690 if ((intr & ERROR_INTR) && fs->state != do_transfer)
645 printk(KERN_ERR "swim3_interrupt, state=%d, dir=%x, intr=%x, err=%x\n", 691 swim3_err("Non-transfer error interrupt: state=%d, dir=%x, intr=%x, err=%x\n",
646 fs->state, rq_data_dir(fd_req), intr, err); 692 fs->state, rq_data_dir(req), intr, err);
647 switch (fs->state) { 693 switch (fs->state) {
648 case locating: 694 case locating:
649 if (intr & SEEN_SECTOR) { 695 if (intr & SEEN_SECTOR) {
@@ -653,10 +699,10 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
653 del_timer(&fs->timeout); 699 del_timer(&fs->timeout);
654 fs->timeout_pending = 0; 700 fs->timeout_pending = 0;
655 if (sw->ctrack == 0xff) { 701 if (sw->ctrack == 0xff) {
656 printk(KERN_ERR "swim3: seen sector but cyl=ff?\n"); 702 swim3_err("%s", "Seen sector but cyl=ff?\n");
657 fs->cur_cyl = -1; 703 fs->cur_cyl = -1;
658 if (fs->retries > 5) { 704 if (fs->retries > 5) {
659 swim3_end_request_cur(-EIO); 705 swim3_end_request(fs, -EIO, 0);
660 fs->state = idle; 706 fs->state = idle;
661 start_request(fs); 707 start_request(fs);
662 } else { 708 } else {
@@ -668,8 +714,8 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
668 fs->cur_cyl = sw->ctrack; 714 fs->cur_cyl = sw->ctrack;
669 fs->cur_sector = sw->csect; 715 fs->cur_sector = sw->csect;
670 if (fs->expect_cyl != -1 && fs->expect_cyl != fs->cur_cyl) 716 if (fs->expect_cyl != -1 && fs->expect_cyl != fs->cur_cyl)
671 printk(KERN_ERR "swim3: expected cyl %d, got %d\n", 717 swim3_err("Expected cyl %d, got %d\n",
672 fs->expect_cyl, fs->cur_cyl); 718 fs->expect_cyl, fs->cur_cyl);
673 fs->state = do_transfer; 719 fs->state = do_transfer;
674 act(fs); 720 act(fs);
675 } 721 }
@@ -704,7 +750,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
704 fs->timeout_pending = 0; 750 fs->timeout_pending = 0;
705 dr = fs->dma; 751 dr = fs->dma;
706 cp = fs->dma_cmd; 752 cp = fs->dma_cmd;
707 if (rq_data_dir(fd_req) == WRITE) 753 if (rq_data_dir(req) == WRITE)
708 ++cp; 754 ++cp;
709 /* 755 /*
710 * Check that the main data transfer has finished. 756 * Check that the main data transfer has finished.
@@ -729,31 +775,32 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
729 if (intr & ERROR_INTR) { 775 if (intr & ERROR_INTR) {
730 n = fs->scount - 1 - resid / 512; 776 n = fs->scount - 1 - resid / 512;
731 if (n > 0) { 777 if (n > 0) {
732 blk_update_request(fd_req, 0, n << 9); 778 blk_update_request(req, 0, n << 9);
733 fs->req_sector += n; 779 fs->req_sector += n;
734 } 780 }
735 if (fs->retries < 5) { 781 if (fs->retries < 5) {
736 ++fs->retries; 782 ++fs->retries;
737 act(fs); 783 act(fs);
738 } else { 784 } else {
739 printk("swim3: error %sing block %ld (err=%x)\n", 785 swim3_err("Error %sing block %ld (err=%x)\n",
740 rq_data_dir(fd_req) == WRITE? "writ": "read", 786 rq_data_dir(req) == WRITE? "writ": "read",
741 (long)blk_rq_pos(fd_req), err); 787 (long)blk_rq_pos(req), err);
742 swim3_end_request_cur(-EIO); 788 swim3_end_request(fs, -EIO, 0);
743 fs->state = idle; 789 fs->state = idle;
744 } 790 }
745 } else { 791 } else {
746 if ((stat & ACTIVE) == 0 || resid != 0) { 792 if ((stat & ACTIVE) == 0 || resid != 0) {
747 /* musta been an error */ 793 /* musta been an error */
748 printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid); 794 swim3_err("fd dma error: stat=%x resid=%d\n", stat, resid);
749 printk(KERN_ERR " state=%d, dir=%x, intr=%x, err=%x\n", 795 swim3_err(" state=%d, dir=%x, intr=%x, err=%x\n",
750 fs->state, rq_data_dir(fd_req), intr, err); 796 fs->state, rq_data_dir(req), intr, err);
751 swim3_end_request_cur(-EIO); 797 swim3_end_request(fs, -EIO, 0);
752 fs->state = idle; 798 fs->state = idle;
753 start_request(fs); 799 start_request(fs);
754 break; 800 break;
755 } 801 }
756 if (swim3_end_request(0, fs->scount << 9)) { 802 fs->retries = 0;
803 if (swim3_end_request(fs, 0, fs->scount << 9)) {
757 fs->req_sector += fs->scount; 804 fs->req_sector += fs->scount;
758 if (fs->req_sector > fs->secpertrack) { 805 if (fs->req_sector > fs->secpertrack) {
759 fs->req_sector -= fs->secpertrack; 806 fs->req_sector -= fs->secpertrack;
@@ -770,8 +817,9 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
770 start_request(fs); 817 start_request(fs);
771 break; 818 break;
772 default: 819 default:
773 printk(KERN_ERR "swim3: don't know what to do in state %d\n", fs->state); 820 swim3_err("Don't know what to do in state %d\n", fs->state);
774 } 821 }
822 spin_unlock_irqrestore(&swim3_lock, flags);
775 return IRQ_HANDLED; 823 return IRQ_HANDLED;
776} 824}
777 825
@@ -781,26 +829,31 @@ static void fd_dma_interrupt(int irq, void *dev_id)
781} 829}
782*/ 830*/
783 831
832/* Called under the mutex to grab exclusive access to a drive */
784static int grab_drive(struct floppy_state *fs, enum swim_state state, 833static int grab_drive(struct floppy_state *fs, enum swim_state state,
785 int interruptible) 834 int interruptible)
786{ 835{
787 unsigned long flags; 836 unsigned long flags;
788 837
789 spin_lock_irqsave(&fs->lock, flags); 838 swim3_dbg("%s", "-> grab drive\n");
790 if (fs->state != idle) { 839
840 spin_lock_irqsave(&swim3_lock, flags);
841 if (fs->state != idle && fs->state != available) {
791 ++fs->wanted; 842 ++fs->wanted;
792 while (fs->state != available) { 843 while (fs->state != available) {
844 spin_unlock_irqrestore(&swim3_lock, flags);
793 if (interruptible && signal_pending(current)) { 845 if (interruptible && signal_pending(current)) {
794 --fs->wanted; 846 --fs->wanted;
795 spin_unlock_irqrestore(&fs->lock, flags);
796 return -EINTR; 847 return -EINTR;
797 } 848 }
798 interruptible_sleep_on(&fs->wait); 849 interruptible_sleep_on(&fs->wait);
850 spin_lock_irqsave(&swim3_lock, flags);
799 } 851 }
800 --fs->wanted; 852 --fs->wanted;
801 } 853 }
802 fs->state = state; 854 fs->state = state;
803 spin_unlock_irqrestore(&fs->lock, flags); 855 spin_unlock_irqrestore(&swim3_lock, flags);
856
804 return 0; 857 return 0;
805} 858}
806 859
@@ -808,10 +861,12 @@ static void release_drive(struct floppy_state *fs)
808{ 861{
809 unsigned long flags; 862 unsigned long flags;
810 863
811 spin_lock_irqsave(&fs->lock, flags); 864 swim3_dbg("%s", "-> release drive\n");
865
866 spin_lock_irqsave(&swim3_lock, flags);
812 fs->state = idle; 867 fs->state = idle;
813 start_request(fs); 868 start_request(fs);
814 spin_unlock_irqrestore(&fs->lock, flags); 869 spin_unlock_irqrestore(&swim3_lock, flags);
815} 870}
816 871
817static int fd_eject(struct floppy_state *fs) 872static int fd_eject(struct floppy_state *fs)
@@ -966,6 +1021,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
966{ 1021{
967 struct floppy_state *fs = disk->private_data; 1022 struct floppy_state *fs = disk->private_data;
968 struct swim3 __iomem *sw = fs->swim3; 1023 struct swim3 __iomem *sw = fs->swim3;
1024
969 mutex_lock(&swim3_mutex); 1025 mutex_lock(&swim3_mutex);
970 if (fs->ref_count > 0 && --fs->ref_count == 0) { 1026 if (fs->ref_count > 0 && --fs->ref_count == 0) {
971 swim3_action(fs, MOTOR_OFF); 1027 swim3_action(fs, MOTOR_OFF);
@@ -1031,30 +1087,48 @@ static const struct block_device_operations floppy_fops = {
1031 .revalidate_disk= floppy_revalidate, 1087 .revalidate_disk= floppy_revalidate,
1032}; 1088};
1033 1089
1090static void swim3_mb_event(struct macio_dev* mdev, int mb_state)
1091{
1092 struct floppy_state *fs = macio_get_drvdata(mdev);
1093 struct swim3 __iomem *sw = fs->swim3;
1094
1095 if (!fs)
1096 return;
1097 if (mb_state != MB_FD)
1098 return;
1099
1100 /* Clear state */
1101 out_8(&sw->intr_enable, 0);
1102 in_8(&sw->intr);
1103 in_8(&sw->error);
1104}
1105
1034static int swim3_add_device(struct macio_dev *mdev, int index) 1106static int swim3_add_device(struct macio_dev *mdev, int index)
1035{ 1107{
1036 struct device_node *swim = mdev->ofdev.dev.of_node; 1108 struct device_node *swim = mdev->ofdev.dev.of_node;
1037 struct floppy_state *fs = &floppy_states[index]; 1109 struct floppy_state *fs = &floppy_states[index];
1038 int rc = -EBUSY; 1110 int rc = -EBUSY;
1039 1111
1112 /* Do this first for message macros */
1113 memset(fs, 0, sizeof(*fs));
1114 fs->mdev = mdev;
1115 fs->index = index;
1116
1040 /* Check & Request resources */ 1117 /* Check & Request resources */
1041 if (macio_resource_count(mdev) < 2) { 1118 if (macio_resource_count(mdev) < 2) {
1042 printk(KERN_WARNING "ifd%d: no address for %s\n", 1119 swim3_err("%s", "No address in device-tree\n");
1043 index, swim->full_name);
1044 return -ENXIO; 1120 return -ENXIO;
1045 } 1121 }
1046 if (macio_irq_count(mdev) < 2) { 1122 if (macio_irq_count(mdev) < 1) {
1047 printk(KERN_WARNING "fd%d: no intrs for device %s\n", 1123 swim3_err("%s", "No interrupt in device-tree\n");
1048 index, swim->full_name); 1124 return -ENXIO;
1049 } 1125 }
1050 if (macio_request_resource(mdev, 0, "swim3 (mmio)")) { 1126 if (macio_request_resource(mdev, 0, "swim3 (mmio)")) {
1051 printk(KERN_ERR "fd%d: can't request mmio resource for %s\n", 1127 swim3_err("%s", "Can't request mmio resource\n");
1052 index, swim->full_name);
1053 return -EBUSY; 1128 return -EBUSY;
1054 } 1129 }
1055 if (macio_request_resource(mdev, 1, "swim3 (dma)")) { 1130 if (macio_request_resource(mdev, 1, "swim3 (dma)")) {
1056 printk(KERN_ERR "fd%d: can't request dma resource for %s\n", 1131 swim3_err("%s", "Can't request dma resource\n");
1057 index, swim->full_name);
1058 macio_release_resource(mdev, 0); 1132 macio_release_resource(mdev, 0);
1059 return -EBUSY; 1133 return -EBUSY;
1060 } 1134 }
@@ -1063,22 +1137,18 @@ static int swim3_add_device(struct macio_dev *mdev, int index)
1063 if (mdev->media_bay == NULL) 1137 if (mdev->media_bay == NULL)
1064 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); 1138 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
1065 1139
1066 memset(fs, 0, sizeof(*fs));
1067 spin_lock_init(&fs->lock);
1068 fs->state = idle; 1140 fs->state = idle;
1069 fs->swim3 = (struct swim3 __iomem *) 1141 fs->swim3 = (struct swim3 __iomem *)
1070 ioremap(macio_resource_start(mdev, 0), 0x200); 1142 ioremap(macio_resource_start(mdev, 0), 0x200);
1071 if (fs->swim3 == NULL) { 1143 if (fs->swim3 == NULL) {
1072 printk("fd%d: couldn't map registers for %s\n", 1144 swim3_err("%s", "Couldn't map mmio registers\n");
1073 index, swim->full_name);
1074 rc = -ENOMEM; 1145 rc = -ENOMEM;
1075 goto out_release; 1146 goto out_release;
1076 } 1147 }
1077 fs->dma = (struct dbdma_regs __iomem *) 1148 fs->dma = (struct dbdma_regs __iomem *)
1078 ioremap(macio_resource_start(mdev, 1), 0x200); 1149 ioremap(macio_resource_start(mdev, 1), 0x200);
1079 if (fs->dma == NULL) { 1150 if (fs->dma == NULL) {
1080 printk("fd%d: couldn't map DMA for %s\n", 1151 swim3_err("%s", "Couldn't map dma registers\n");
1081 index, swim->full_name);
1082 iounmap(fs->swim3); 1152 iounmap(fs->swim3);
1083 rc = -ENOMEM; 1153 rc = -ENOMEM;
1084 goto out_release; 1154 goto out_release;
@@ -1090,31 +1160,25 @@ static int swim3_add_device(struct macio_dev *mdev, int index)
1090 fs->secpercyl = 36; 1160 fs->secpercyl = 36;
1091 fs->secpertrack = 18; 1161 fs->secpertrack = 18;
1092 fs->total_secs = 2880; 1162 fs->total_secs = 2880;
1093 fs->mdev = mdev;
1094 init_waitqueue_head(&fs->wait); 1163 init_waitqueue_head(&fs->wait);
1095 1164
1096 fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space); 1165 fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space);
1097 memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd)); 1166 memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd));
1098 st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); 1167 st_le16(&fs->dma_cmd[1].command, DBDMA_STOP);
1099 1168
1169 if (mdev->media_bay == NULL || check_media_bay(mdev->media_bay) == MB_FD)
1170 swim3_mb_event(mdev, MB_FD);
1171
1100 if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { 1172 if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) {
1101 printk(KERN_ERR "fd%d: couldn't request irq %d for %s\n", 1173 swim3_err("%s", "Couldn't request interrupt\n");
1102 index, fs->swim3_intr, swim->full_name);
1103 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); 1174 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
1104 goto out_unmap; 1175 goto out_unmap;
1105 return -EBUSY; 1176 return -EBUSY;
1106 } 1177 }
1107/*
1108 if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) {
1109 printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA",
1110 fs->dma_intr);
1111 return -EBUSY;
1112 }
1113*/
1114 1178
1115 init_timer(&fs->timeout); 1179 init_timer(&fs->timeout);
1116 1180
1117 printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, 1181 swim3_info("SWIM3 floppy controller %s\n",
1118 mdev->media_bay ? "in media bay" : ""); 1182 mdev->media_bay ? "in media bay" : "");
1119 1183
1120 return 0; 1184 return 0;
@@ -1132,41 +1196,42 @@ static int swim3_add_device(struct macio_dev *mdev, int index)
1132 1196
1133static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match) 1197static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match)
1134{ 1198{
1135 int i, rc;
1136 struct gendisk *disk; 1199 struct gendisk *disk;
1200 int index, rc;
1201
1202 index = floppy_count++;
1203 if (index >= MAX_FLOPPIES)
1204 return -ENXIO;
1137 1205
1138 /* Add the drive */ 1206 /* Add the drive */
1139 rc = swim3_add_device(mdev, floppy_count); 1207 rc = swim3_add_device(mdev, index);
1140 if (rc) 1208 if (rc)
1141 return rc; 1209 return rc;
1210 /* Now register that disk. Same comment about failure handling */
1211 disk = disks[index] = alloc_disk(1);
1212 if (disk == NULL)
1213 return -ENOMEM;
1214 disk->queue = blk_init_queue(do_fd_request, &swim3_lock);
1215 if (disk->queue == NULL) {
1216 put_disk(disk);
1217 return -ENOMEM;
1218 }
1219 disk->queue->queuedata = &floppy_states[index];
1142 1220
1143 /* Now create the queue if not there yet */ 1221 if (index == 0) {
1144 if (swim3_queue == NULL) {
1145 /* If we failed, there isn't much we can do as the driver is still 1222 /* If we failed, there isn't much we can do as the driver is still
1146 * too dumb to remove the device, just bail out 1223 * too dumb to remove the device, just bail out
1147 */ 1224 */
1148 if (register_blkdev(FLOPPY_MAJOR, "fd")) 1225 if (register_blkdev(FLOPPY_MAJOR, "fd"))
1149 return 0; 1226 return 0;
1150 swim3_queue = blk_init_queue(do_fd_request, &swim3_lock);
1151 if (swim3_queue == NULL) {
1152 unregister_blkdev(FLOPPY_MAJOR, "fd");
1153 return 0;
1154 }
1155 } 1227 }
1156 1228
1157 /* Now register that disk. Same comment about failure handling */
1158 i = floppy_count++;
1159 disk = disks[i] = alloc_disk(1);
1160 if (disk == NULL)
1161 return 0;
1162
1163 disk->major = FLOPPY_MAJOR; 1229 disk->major = FLOPPY_MAJOR;
1164 disk->first_minor = i; 1230 disk->first_minor = index;
1165 disk->fops = &floppy_fops; 1231 disk->fops = &floppy_fops;
1166 disk->private_data = &floppy_states[i]; 1232 disk->private_data = &floppy_states[index];
1167 disk->queue = swim3_queue;
1168 disk->flags |= GENHD_FL_REMOVABLE; 1233 disk->flags |= GENHD_FL_REMOVABLE;
1169 sprintf(disk->disk_name, "fd%d", i); 1234 sprintf(disk->disk_name, "fd%d", index);
1170 set_capacity(disk, 2880); 1235 set_capacity(disk, 2880);
1171 add_disk(disk); 1236 add_disk(disk);
1172 1237
@@ -1194,6 +1259,9 @@ static struct macio_driver swim3_driver =
1194 .of_match_table = swim3_match, 1259 .of_match_table = swim3_match,
1195 }, 1260 },
1196 .probe = swim3_attach, 1261 .probe = swim3_attach,
1262#ifdef CONFIG_PMAC_MEDIABAY
1263 .mediabay_event = swim3_mb_event,
1264#endif
1197#if 0 1265#if 0
1198 .suspend = swim3_suspend, 1266 .suspend = swim3_suspend,
1199 .resume = swim3_resume, 1267 .resume = swim3_resume,