public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [CFT][PATCH] ide-floppy cleanups/media change detection (5/5)
@ 2002-01-13  2:54 Kevin P. Fleming
  2002-01-13  3:17 ` Alan Cox
  0 siblings, 1 reply; 2+ messages in thread
From: Kevin P. Fleming @ 2002-01-13  2:54 UTC (permalink / raw)
  To: linux-kernel; +Cc: Paul Bristow

Patch 5 follows, implementing media change detection as follows:

The ide-floppy module will now cause media revalidation under these
circumstances:

- when media has been exchanged for different-sized media
- when media has been previously ejected using the CDROMEJECT ioctl
- when media has been previously formatted using the *FORMAT ioctl
- when media was not previously present

For these operations to happen properly, a small patch to ide-probe.c
(previously sent to Marcelo and queued for 2.4.18-preX) is required so that
the gendisk layer will treat ide-floppy devices as removable media devices.
In addition, if devfs is in use, a small (<20 lines) patch to
fs/partitions/check.c is required so that the devfs partition entries will
be kept in sync with the media when revalidations occur. Richard Gooch will
be including that patch in an upcoming devfs update patch.

--- linux-4/drivers/ide/ide-floppy.c Sat Jan 12 19:00:33 2002
+++ linux-5/drivers/ide/ide-floppy.c Sat Jan 12 19:12:31 2002
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/ide-floppy.c Version 0.97.sv Jan 14 2001
+ * linux/drivers/ide/ide-floppy.c Version 0.98.sv Jan 11 2002
  *
  * Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
  * Copyright (C) 2000 - 2001 Paul Bristow <paul@paulbristow.net>
@@ -71,9 +71,12 @@
  *                       including set_bit patch from Rusty Russel
  * Ver 0.97  Jul 22 01   Merge 0.91-0.96 onto 0.9.sv for ac series
  * Ver 0.97.sv Aug 3 01  Backported from 2.4.7-ac3
+ * Ver 0.98.sv Jan 11 02 Implemented media change detection, removed large
+ *                       structures allocated on the stack, moved
lock/unlock
+ *                       code into a separate function
<kevin@labsysgrp.com>
  */

-#define IDEFLOPPY_VERSION "0.97.sv"
+#define IDEFLOPPY_VERSION "0.98.sv"

 #include <linux/config.h>
 #include <linux/module.h>
@@ -282,7 +285,8 @@
   * Device information
   */
  int blocks, block_size, bs_factor;   /* Current format */
- idefloppy_capacity_descriptor_t capacity;  /* Last format capacity */
+ idefloppy_capacity_descriptor_t capacity;  /* Current media capacity */
+ int capacity_invalid;                                   /* Is the current
capacity unusable? */
  idefloppy_flexible_disk_page_t flexible_disk_page; /* Copy of the flexible
disk page */
  int wp;       /* Write protect */
  int srfp;   /* Supports format progress report */
@@ -1359,22 +1363,14 @@
 }

 /*
- * Determine if a media is present in the floppy drive, and if so,
- * its LBA capacity.
+ *      Get the current capacity descriptor for the drive.
  */
-static int idefloppy_get_capacity (ide_drive_t *drive)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
+static int idefloppy_get_current_capacity_descriptor (ide_drive_t *drive,
idefloppy_capacity_descriptor_t *descriptor) {
  idefloppy_pc_t *pc;
  idefloppy_capacity_header_t *header;
- idefloppy_capacity_descriptor_t *descriptor;
- int i, descriptors, rc = 1, blocks, length;
+ idefloppy_floppy_t *floppy = drive->driver_data;
+ int rc = 1;

- drive->bios_cyl = 0;
- drive->bios_head = drive->bios_sect = 0;
- floppy->blocks = floppy->bs_factor = 0;
- drive->part[0].nr_sects = 0;
-
  if ((pc = (idefloppy_pc_t *) kmalloc (sizeof (idefloppy_pc_t),
GFP_KERNEL)) == NULL) {
   printk (KERN_ERR "ide-floppy: %s: Can't allocate a packet command
structure\n", drive->name);
   return 1;
@@ -1383,50 +1379,70 @@
  idefloppy_create_read_capacity_cmd (pc);
  if (idefloppy_queue_pc_tail (drive, pc)) {
   printk (KERN_ERR "ide-floppy: Can't get floppy parameters\n");
-  kfree (pc);
-  return 1;
+ } else {
+  header = (idefloppy_capacity_header_t *) pc->buffer;
+  *descriptor = *((idefloppy_capacity_descriptor_t *) (header + 1));
+  descriptor->blocks = ntohl(descriptor->blocks);
+  descriptor->length = ntohs(descriptor->length);
+/* Clik! drive returns CAPACITY_UNFORMATTED instead of CAPACITY_CURRENT */
+  if ((descriptor->dc == CAPACITY_UNFORMATTED) &&
test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags))
+   descriptor->dc = CAPACITY_CURRENT;
+  rc = 0;
  }
- header = (idefloppy_capacity_header_t *) pc->buffer;
- descriptors = header->length / sizeof (idefloppy_capacity_descriptor_t);
- descriptor = (idefloppy_capacity_descriptor_t *) (header + 1);
-
- for (i = 0; i < descriptors; i++, descriptor++) {
-                blocks = descriptor->blocks = ntohl (descriptor->blocks);
-                length = descriptor->length = ntohs (descriptor->length);
+ kfree (pc);
+ return rc;
+}

-  if (!i)
-  {
-           switch (descriptor->dc) {
-                case CAPACITY_UNFORMATTED: /* Clik! drive returns this
instead of CAPACITY_CURRENT */
-                        if (!test_bit(IDEFLOPPY_CLIK_DRIVE,
&floppy->flags))
-                                break; /* If it is not a clik drive, break
out (maintains previous driver behaviour) */
-                case CAPACITY_CURRENT: /* Normal Zip/LS-120 disks */
-                        if (memcmp (descriptor, &floppy->capacity, sizeof
(idefloppy_capacity_descriptor_t)))
-                                printk (KERN_INFO "%s: %dkB, %d blocks, %d
sector size\n", drive->name, blocks * length / 1024, blocks, length);
-                        floppy->capacity = *descriptor;
-                        if (!length || length % 512)
-                                printk (KERN_NOTICE "%s: %d bytes block
size not supported\n", drive->name, length);
-                        else {
-                                floppy->blocks = blocks;
-                                floppy->block_size = length;
-                                if ((floppy->bs_factor = length / 512) !=
1)
-                                        printk (KERN_NOTICE "%s: warning:
non 512 bytes block size not fully supported\n", drive->name);
-                                rc = 0;
-                        }
-                        break;
-                case CAPACITY_NO_CARTRIDGE:
-                        /* This is a KERN_ERR so it appears on screen for
the user to see */
-                        printk (KERN_ERR "%s: No disk in drive\n",
drive->name);
-                                        break;
-                case CAPACITY_INVALID:
-                        printk (KERN_ERR "%s: Invalid capacity for disk in
drive\n", drive->name);
-                                        break;
-  }
-  }
-  if (!i) {
-  IDEFLOPPY_DEBUG( "Descriptor 0 Code: %d\n", descriptor->dc);
-  }
-  IDEFLOPPY_DEBUG( "Descriptor %d: %dkB, %d blocks, %d sector size\n", i,
blocks * length / 1024, blocks, length);
+/*
+ * Determine if a media is present in the floppy drive, and if so,
+ * its LBA capacity.
+ */
+static int idefloppy_update_capacity (ide_drive_t *drive,
idefloppy_capacity_descriptor_t *descriptor, int quiet)
+{
+ idefloppy_floppy_t *floppy = drive->driver_data;
+
+/* If capacity descriptor has not changed, return previous "valid" status.
*/
+ if (!memcmp(descriptor, &floppy->capacity, sizeof
(idefloppy_capacity_descriptor_t))) {
+  return floppy->capacity_invalid;
+ }
+
+/* Assume unusable capacity unless proven otherwise */
+ floppy->capacity_invalid = 1;
+ switch (descriptor->dc) {
+ case CAPACITY_UNFORMATTED:
+  break;
+ case CAPACITY_NO_CARTRIDGE:
+  /* This is a KERN_ERR so it appears on screen for the user to see */
+  if (!quiet)
+   printk (KERN_ERR "%s: No disk in drive\n", drive->name);
+  break;
+ case CAPACITY_INVALID:
+  if (!quiet)
+   printk (KERN_ERR "%s: Invalid capacity for disk in drive\n",
drive->name);
+  break;
+ case CAPACITY_CURRENT:
+  if (!quiet)
+   printk (KERN_INFO "%s: %dkB, %d blocks, %d sector size\n", drive->name,
descriptor->blocks * descriptor->length / 1024, descriptor->blocks,
descriptor->length);
+  if (!descriptor->length || descriptor->length % 512) {
+   if (!quiet)
+    printk (KERN_NOTICE "%s: %d bytes block size not supported\n",
drive->name, descriptor->length);
+  } else
+   floppy->capacity_invalid = 0;
+  break;
+ }
+
+ floppy->capacity = *descriptor;
+
+ if (!floppy->capacity_invalid) {
+  floppy->blocks = descriptor->blocks;
+  floppy->block_size = descriptor->length;
+  if ((floppy->bs_factor = (descriptor->length / 512)) != 1)
+   if (!quiet)
+    printk (KERN_NOTICE "%s: warning: non 512 bytes block size not fully
supported\n", drive->name);
+  drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;
+ } else {
+  floppy->blocks = floppy->block_size = floppy->bs_factor = 0;
+  drive->part[0].nr_sects = 0;
  }

  /* Clik! disk does not support get_flexible_disk_page */
@@ -1435,9 +1451,7 @@
   (void) idefloppy_get_flexible_disk_page (drive);
  }

- drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;
- kfree (pc);
- return rc;
+ return floppy->capacity_invalid;
 }

 /*
@@ -1563,6 +1577,7 @@
  int length;
  int flags;
  idefloppy_pc_t *pc;
+ idefloppy_floppy_t *floppy = drive->driver_data;

  if (get_user(blocks, arg)
      || get_user(length, arg+1)
@@ -1583,6 +1598,7 @@
   kfree (pc);
                 return (-EIO);
         }
+ set_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
  kfree (pc);
  return (0);
 }
@@ -1692,6 +1708,7 @@
   memset (pc, 0, sizeof (idefloppy_pc_t));
   idefloppy_create_start_stop_cmd (pc, 2);
   (void) idefloppy_queue_pc_tail (drive, pc);
+  set_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
   kfree (pc);
   return 0;
  case CDROM_LOCKDOOR:
@@ -1758,6 +1775,7 @@
 {
  idefloppy_floppy_t *floppy = drive->driver_data;
  idefloppy_pc_t *pc;
+ idefloppy_capacity_descriptor_t descriptor;

 #if IDEFLOPPY_DEBUG_LOG
  printk (KERN_INFO "Reached idefloppy_open\n");
@@ -1779,7 +1797,8 @@
    (void) idefloppy_queue_pc_tail (drive, pc);
   }

-  if (idefloppy_get_capacity (drive)
+  (void) idefloppy_get_current_capacity_descriptor (drive, &descriptor);
+  if (idefloppy_update_capacity (drive, &descriptor, 0)
      && (filp->f_flags & O_NDELAY) == 0
       /*
       ** Allow O_NDELAY to open a drive without a disk, or with
@@ -1799,7 +1818,6 @@
    MOD_DEC_USE_COUNT;
    return -EROFS;
   }
-  set_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
   (void) idefloppy_lockunlock (drive, 1);
   check_disk_change(inode->i_rdev);
   kfree (pc);
@@ -1833,13 +1851,29 @@
 }

 /*
- * Check media change. Use a simple algorithm for now.
+ * Check media change.
+ *      The media change bit may already have been set by an eject or
+ *      format ioctl. If not, check the current media capacity, and if
+ *      it is different than what we last saw, the media has been changed
:-)
+ *      Otherwise return "no change", because we have no way to identify
+ *      individual media.
  */
 static int idefloppy_media_change (ide_drive_t *drive)
 {
  idefloppy_floppy_t *floppy = drive->driver_data;
+ idefloppy_capacity_descriptor_t descriptor;
+ int media_changed;

- return test_and_clear_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
+ media_changed = test_and_clear_bit (IDEFLOPPY_MEDIA_CHANGED,
&floppy->flags);
+
+ if (!idefloppy_get_current_capacity_descriptor (drive, &descriptor)) {
+  if (memcmp (&descriptor, &floppy->capacity,
sizeof(idefloppy_capacity_descriptor_t))) {
+   (void) idefloppy_update_capacity (drive, &descriptor, 0);
+   media_changed = 1;
+  }
+ }
+
+ return media_changed;
 }

 /*
@@ -2001,6 +2035,7 @@
  struct idefloppy_id_gcw gcw;
  int major = HWIF(drive)->major, i;
  int minor = drive->select.b.unit << PARTN_BITS;
+ idefloppy_capacity_descriptor_t descriptor;

  *((unsigned short *) &gcw) = drive->id->config;
  drive->driver_data = floppy;
@@ -2040,7 +2075,8 @@
  }


- (void) idefloppy_get_capacity (drive);
+ (void) idefloppy_get_current_capacity_descriptor (drive, &descriptor);
+ (void) idefloppy_update_capacity (drive, &descriptor, 1);
  idefloppy_add_settings(drive);
  for (i = 0; i < MAX_DRIVES; ++i) {
   ide_hwif_t *hwif = HWIF(drive);






^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [CFT][PATCH] ide-floppy cleanups/media change detection (5/5)
  2002-01-13  2:54 [CFT][PATCH] ide-floppy cleanups/media change detection (5/5) Kevin P. Fleming
@ 2002-01-13  3:17 ` Alan Cox
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Cox @ 2002-01-13  3:17 UTC (permalink / raw)
  To: Kevin P. Fleming; +Cc: linux-kernel, Paul Bristow

> Patch 5 follows, implementing media change detection as follows:

Please don't post patches with ms lookout. You lose the tab/spaces and they
get wrapped and mangled into oblivion.

Secondly - you probably want to pick up Andre Hedrick's linux-ide stuff that
is waiting to go in (www.linux-ide.org) and merge against that then submit
it to Andre. That may also help you in other ways as the new core code is
somewhat cleaner

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-01-13  3:05 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-01-13  2:54 [CFT][PATCH] ide-floppy cleanups/media change detection (5/5) Kevin P. Fleming
2002-01-13  3:17 ` Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox