📄 ide-floppy.c
字号:
return (0);}/*** Send ATAPI_FORMAT_UNIT to the drive.**** Userland gives us the following structure:**** struct idefloppy_format_command {** int nblocks;** int blocksize;** int flags;** } ;**** flags is a bitmask, currently, the only defined flag is:**** 0x01 - verify media after format.*/static int idefloppy_begin_format(ide_drive_t *drive, struct inode *inode, struct file *file, int *arg){ int blocks; int length; int flags; idefloppy_pc_t pc; if (get_user(blocks, arg) || get_user(length, arg+1) || get_user(flags, arg+2)) { return (-EFAULT); } (void) idefloppy_get_capability_page (drive); /* Get the SFRP bit */ idefloppy_create_format_unit_cmd(&pc, blocks, length, flags); if (idefloppy_queue_pc_tail (drive, &pc)) { return (-EIO); } return (0);}/*** Get ATAPI_FORMAT_UNIT progress indication.**** Userland gives a pointer to an int. The int is set to a progresss** indicator 0-65536, with 65536=100%.**** If the drive does not support format progress indication, we just check** the dsc bit, and return either 0 or 65536.*/static int idefloppy_get_format_progress(ide_drive_t *drive, struct inode *inode, struct file *file, int *arg){ idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_pc_t pc; int progress_indication=0x10000; if (floppy->srfp) { idefloppy_create_request_sense_cmd(&pc); if (idefloppy_queue_pc_tail (drive, &pc)) { return (-EIO); } if (floppy->sense_key == 2 && floppy->asc == 4 && floppy->ascq == 4) { progress_indication=floppy->progress_indication; } /* Else assume format_unit has finished, and we're ** at 0x10000 */ } else { idefloppy_status_reg_t status; unsigned long flags; __save_flags(flags); __cli(); status.all=GET_STAT(); __restore_flags(flags); progress_indication= !status.b.dsc ? 0:0x10000; } if (put_user(progress_indication, arg)) return (-EFAULT); return (0);}/* * Our special ide-floppy ioctl's. * * Currently there aren't any ioctl's. */static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ idefloppy_pc_t pc; idefloppy_floppy_t *floppy = drive->driver_data; int prevent = (arg) ? 1 : 0; switch (cmd) { case CDROMEJECT: prevent = 0; /* fall through */ case CDROM_LOCKDOOR: if (drive->usage > 1) return -EBUSY; /* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */ if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { idefloppy_create_prevent_cmd (&pc, prevent); (void) idefloppy_queue_pc_tail (drive, &pc); } if (cmd == CDROMEJECT) { idefloppy_create_start_stop_cmd (&pc, 2); (void) idefloppy_queue_pc_tail (drive, &pc); } return 0; case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED: return (0); case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY: return (idefloppy_get_format_capacities(drive, inode, file, (int *)arg)); case IDEFLOPPY_IOCTL_FORMAT_START: if (!(file->f_mode & 2)) return (-EPERM); { idefloppy_floppy_t *floppy = drive->driver_data; if (drive->usage > 1) { /* Don't format if someone is using the disk */ clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); return -EBUSY; } else { int rc; set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); rc=idefloppy_begin_format(drive, inode, file, (int *)arg); if (rc) clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); return (rc); /* ** Note, the bit will be cleared when the device is ** closed. This is the cleanest way to handle the ** situation where the drive does not support ** format progress reporting. */ } } case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: return (idefloppy_get_format_progress(drive, inode, file, (int *)arg)); } return -EIO;}/* * Our open/release functions */static int idefloppy_open (struct inode *inode, struct file *filp, ide_drive_t *drive){ idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_pc_t pc; #if IDEFLOPPY_DEBUG_LOG printk (KERN_INFO "Reached idefloppy_open\n");#endif /* IDEFLOPPY_DEBUG_LOG */ MOD_INC_USE_COUNT; if (drive->usage == 1) { clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); /* Just in case */ idefloppy_create_test_unit_ready_cmd(&pc); if (idefloppy_queue_pc_tail(drive, &pc)) { idefloppy_create_start_stop_cmd (&pc, 1); (void) idefloppy_queue_pc_tail (drive, &pc); } if (idefloppy_get_capacity (drive) && (filp->f_flags & O_NDELAY) == 0 /* ** Allow O_NDELAY to open a drive without a disk, or with ** an unreadable disk, so that we can get the format ** capacity of the drive or begin the format - Sam */ ) { drive->usage--; MOD_DEC_USE_COUNT; return -EIO; } if (floppy->wp && (filp->f_mode & 2)) { drive->usage--; MOD_DEC_USE_COUNT; return -EROFS; } set_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags); /* IOMEGA Clik! drives do not support lock/unlock commands */ if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { idefloppy_create_prevent_cmd (&pc, 1); (void) idefloppy_queue_pc_tail (drive, &pc); } check_disk_change(inode->i_rdev); } else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) { drive->usage--; MOD_DEC_USE_COUNT; return -EBUSY; } return 0;}static void idefloppy_release (struct inode *inode, struct file *filp, ide_drive_t *drive){ idefloppy_pc_t pc; #if IDEFLOPPY_DEBUG_LOG printk (KERN_INFO "Reached idefloppy_release\n");#endif /* IDEFLOPPY_DEBUG_LOG */ if (!drive->usage) { idefloppy_floppy_t *floppy = drive->driver_data; invalidate_bdev (inode->i_bdev, 0); /* IOMEGA Clik! drives do not support lock/unlock commands */ if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { idefloppy_create_prevent_cmd (&pc, 0); (void) idefloppy_queue_pc_tail (drive, &pc); } clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); } MOD_DEC_USE_COUNT;}/* * Check media change. Use a simple algorithm for now. */static int idefloppy_media_change (ide_drive_t *drive){ idefloppy_floppy_t *floppy = drive->driver_data; return test_and_clear_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);}/* * Revalidate the new media. Should set blk_size[] */static void idefloppy_revalidate (ide_drive_t *drive){ grok_partitions(HWIF(drive)->gd, drive->select.b.unit, 1<<PARTN_BITS, current_capacity(drive));}/* * Return the current floppy capacity to ide.c. */static unsigned long idefloppy_capacity (ide_drive_t *drive){ idefloppy_floppy_t *floppy = drive->driver_data; unsigned long capacity = floppy->blocks * floppy->bs_factor; return capacity;}/* * idefloppy_identify_device checks if we can support a drive, * based on the ATAPI IDENTIFY command results. */static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id){ struct idefloppy_id_gcw gcw;#if IDEFLOPPY_DEBUG_INFO unsigned short mask,i; char buffer[80];#endif /* IDEFLOPPY_DEBUG_INFO */ *((unsigned short *) &gcw) = id->config;#ifdef CONFIG_PPC /* kludge for Apple PowerBook internal zip */ if ((gcw.device_type == 5) && !strstr(id->model, "CD-ROM") && strstr(id->model, "ZIP")) gcw.device_type = 0; #endif#if IDEFLOPPY_DEBUG_INFO printk (KERN_INFO "Dumping ATAPI Identify Device floppy parameters\n"); switch (gcw.protocol) { case 0: case 1: sprintf (buffer, "ATA");break; case 2: sprintf (buffer, "ATAPI");break; case 3: sprintf (buffer, "Reserved (Unknown to ide-floppy)");break; } printk (KERN_INFO "Protocol Type: %s\n", buffer); switch (gcw.device_type) { case 0: sprintf (buffer, "Direct-access Device");break; case 1: sprintf (buffer, "Streaming Tape Device");break; case 2: case 3: case 4: sprintf (buffer, "Reserved");break; case 5: sprintf (buffer, "CD-ROM Device");break; case 6: sprintf (buffer, "Reserved"); case 7: sprintf (buffer, "Optical memory Device");break; case 0x1f: sprintf (buffer, "Unknown or no Device type");break; default: sprintf (buffer, "Reserved"); } printk (KERN_INFO "Device Type: %x - %s\n", gcw.device_type, buffer); printk (KERN_INFO "Removable: %s\n",gcw.removable ? "Yes":"No"); switch (gcw.drq_type) { case 0: sprintf (buffer, "Microprocessor DRQ");break; case 1: sprintf (buffer, "Interrupt DRQ");break; case 2: sprintf (buffer, "Accelerated DRQ");break; case 3: sprintf (buffer, "Reserved");break; } printk (KERN_INFO "Command Packet DRQ Type: %s\n", buffer); switch (gcw.packet_size) { case 0: sprintf (buffer, "12 bytes");break; case 1: sprintf (buffer, "16 bytes");break; default: sprintf (buffer, "Reserved");break; } printk (KERN_INFO "Command Packet Size: %s\n", buffer); printk (KERN_INFO "Model: %.40s\n",id->model); printk (KERN_INFO "Firmware Revision: %.8s\n",id->fw_rev); printk (KERN_INFO "Serial Number: %.20s\n",id->serial_no); printk (KERN_INFO "Write buffer size(?): %d bytes\n",id->buf_size*512); printk (KERN_INFO "DMA: %s",id->capability & 0x01 ? "Yes\n":"No\n"); printk (KERN_INFO "LBA: %s",id->capability & 0x02 ? "Yes\n":"No\n"); printk (KERN_INFO "IORDY can be disabled: %s",id->capability & 0x04 ? "Yes\n":"No\n"); printk (KERN_INFO "IORDY supported: %s",id->capability & 0x08 ? "Yes\n":"Unknown\n"); printk (KERN_INFO "ATAPI overlap supported: %s",id->capability & 0x20 ? "Yes\n":"No\n"); printk (KERN_INFO "PIO Cycle Timing Category: %d\n",id->tPIO); printk (KERN_INFO "DMA Cycle Timing Category: %d\n",id->tDMA); printk (KERN_INFO "Single Word DMA supported modes:\n"); for (i=0,mask=1;i<8;i++,mask=mask << 1) { if (id->dma_1word & mask) printk (KERN_INFO " Mode %d%s\n", i, (id->dma_1word & (mask << 8)) ? " (active)" : ""); } printk (KERN_INFO "Multi Word DMA supported modes:\n"); for (i=0,mask=1;i<8;i++,mask=mask << 1) { if (id->dma_mword & mask) printk (KERN_INFO " Mode %d%s\n", i, (id->dma_mword & (mask << 8)) ? " (active)" : ""); } if (id->field_valid & 0x0002) { printk (KERN_INFO "Enhanced PIO Modes: %s\n",id->eide_pio_modes & 1 ? "Mode 3":"None"); if (id->eide_dma_min == 0) sprintf (buffer, "Not supported"); else sprintf (buffer, "%d ns",id->eide_dma_min); printk (KERN_INFO "Minimum Multi-word DMA cycle per word: %s\n", buffer); if (id->eide_dma_time == 0) sprintf (buffer, "Not supported"); else sprintf (buffer, "%d ns",id->eide_dma_time); printk (KERN_INFO "Manufacturer\'s Recommended Multi-word cycle: %s\n", buffer); if (id->eide_pio == 0) sprintf (buffer, "Not supported"); else sprintf (buffer, "%d ns",id->eide_pio); printk (KERN_INFO "Minimum PIO cycle without IORDY: %s\n", buffer); if (id->eide_pio_iordy == 0) sprintf (buffer, "Not supported"); else sprintf (buffer, "%d ns",id->eide_pio_iordy); printk (KERN_INFO "Minimum PIO cycle with IORDY: %s\n", buffer); } else pr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -