diff options
Diffstat (limited to 'drivers/block')
30 files changed, 240 insertions, 3216 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 92bf868ca056..84d6aa500e26 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -17,8 +17,8 @@ */ -#define DAC960_DriverVersion "2.5.48" -#define DAC960_DriverDate "14 May 2006" +#define DAC960_DriverVersion "2.5.49" +#define DAC960_DriverDate "21 Aug 2007" #include <linux/module.h> @@ -31,6 +31,7 @@ #include <linux/genhd.h> #include <linux/hdreg.h> #include <linux/blkpg.h> +#include <linux/dma-mapping.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/mm.h> @@ -1165,9 +1166,9 @@ static bool DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T int i; - if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V1_PciDmaMask)) + if (pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK)) return DAC960_Failure(Controller, "DMA mask out of range"); - Controller->BounceBufferLimit = DAC690_V1_PciDmaMask; + Controller->BounceBufferLimit = DMA_32BIT_MASK; if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) { CommandMailboxesSize = 0; @@ -1368,9 +1369,12 @@ static bool DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T dma_addr_t CommandMailboxDMA; DAC960_V2_CommandStatus_T CommandStatus; - if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V2_PciDmaMask)) - return DAC960_Failure(Controller, "DMA mask out of range"); - Controller->BounceBufferLimit = DAC690_V2_PciDmaMask; + if (!pci_set_dma_mask(Controller->PCIDevice, DMA_64BIT_MASK)) + Controller->BounceBufferLimit = DMA_64BIT_MASK; + else if (!pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK)) + Controller->BounceBufferLimit = DMA_32BIT_MASK; + else + return DAC960_Failure(Controller, "DMA mask out of range"); /* This is a temporary dma mapping, used only in the scope of this function */ CommandMailbox = pci_alloc_consistent(PCI_Device, diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h index f5e2436c39aa..85fa9bb63759 100644 --- a/drivers/block/DAC960.h +++ b/drivers/block/DAC960.h @@ -61,13 +61,6 @@ #define DAC960_V2_MaxPhysicalDevices 272 /* - Define the pci dma mask supported by DAC960 V1 and V2 Firmware Controlers - */ - -#define DAC690_V1_PciDmaMask 0xffffffff -#define DAC690_V2_PciDmaMask 0xffffffffffffffffULL - -/* Define a 32/64 bit I/O Address data type. */ diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index b4c8319138b2..4245b7f80a49 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -2,9 +2,18 @@ # Block device driver configuration # -if BLOCK +menuconfig BLK_DEV + bool "Block devices" + depends on BLOCK + default y + ---help--- + Say Y here to get to see options for various different block device + drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled; + only do this if you know what you are doing. -menu "Block devices" +if BLK_DEV config BLK_DEV_FD tristate "Normal floppy disk support" @@ -56,51 +65,10 @@ config AMIGA_Z2RAM To compile this driver as a module, choose M here: the module will be called z2ram. -config ATARI_ACSI - tristate "Atari ACSI support" - depends on ATARI && BROKEN - ---help--- - This enables support for the Atari ACSI interface. The driver - supports hard disks and CD-ROMs, which have 512-byte sectors, or can - be switched to that mode. Due to the ACSI command format, only disks - up to 1 GB are supported. Special support for certain ACSI to SCSI - adapters, which could relax that, isn't included yet. The ACSI - driver is also the basis for certain other drivers for devices - attached to the ACSI bus: Atari SLM laser printer, BioNet-100 - Ethernet, and PAMsNet Ethernet. If you want to use one of these - devices, you need ACSI support, too. - - To compile this driver as a module, choose M here: the - module will be called acsi. - -comment "Some devices (e.g. CD jukebox) support multiple LUNs" - depends on ATARI && ATARI_ACSI - -config ACSI_MULTI_LUN - bool "Probe all LUNs on each ACSI device" - depends on ATARI_ACSI - help - If you have a ACSI device that supports more than one LUN (Logical - Unit Number), e.g. a CD jukebox, you should say Y here so that all - will be found by the ACSI driver. An ACSI device with multiple LUNs - acts logically like multiple ACSI devices. The vast majority of ACSI - devices have only one LUN, and so most people can say N here and - should in fact do so, because it is safer. - -config ATARI_SLM - tristate "Atari SLM laser printer support" - depends on ATARI && ATARI_ACSI!=n - help - If you have an Atari SLM laser printer, say Y to include support for - it in the kernel. Otherwise, say N. This driver is also available as - a module ( = code which can be inserted in and removed from the - running kernel whenever you want). The module will be called - acsi_slm. Be warned: the driver needs much ST-RAM and can cause - problems due to that fact! - config BLK_DEV_XD tristate "XT hard disk support" depends on ISA && ISA_DMA_API + select CHECK_SIGNATURE help Very old 8 bit hard disk controllers used in the IBM XT computer will be supported if you say Y here. @@ -141,7 +109,7 @@ source "drivers/block/paride/Kconfig" config BLK_CPQ_DA tristate "Compaq SMART2 support" - depends on PCI + depends on PCI && VIRT_TO_BUS help This is the driver for Compaq Smart Array controllers. Everyone using these boards should say Y here. See the file @@ -451,8 +419,28 @@ config ATA_OVER_ETH This driver provides Support for ATA over Ethernet block devices like the Coraid EtherDrive (R) Storage Blade. +config SUNVDC + tristate "Sun Virtual Disk Client support" + depends on SUN_LDOMS + help + Support for virtual disk devices as a client under Sun + Logical Domains. + source "drivers/s390/block/Kconfig" -endmenu +config XILINX_SYSACE + tristate "Xilinx SystemACE support" + depends on 4xx + help + Include support for the Xilinx SystemACE CompactFlash interface + +config XEN_BLKDEV_FRONTEND + tristate "Xen virtual block device support" + depends on XEN + default y + help + This driver implements the front-end of the Xen virtual + block device driver. It communicates with a back-end driver + in another domain which drives the actual block device. -endif +endif # BLK_DEV diff --git a/drivers/block/Makefile b/drivers/block/Makefile index dd88e33c1eb1..014e72121b5a 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -8,9 +8,8 @@ obj-$(CONFIG_MAC_FLOPPY) += swim3.o obj-$(CONFIG_BLK_DEV_FD) += floppy.o obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o +obj-$(CONFIG_PS3_DISK) += ps3disk.o obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o -obj-$(CONFIG_ATARI_ACSI) += acsi.o -obj-$(CONFIG_ATARI_SLM) += acsi_slm.o obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o obj-$(CONFIG_BLK_DEV_RAM) += rd.o obj-$(CONFIG_BLK_DEV_LOOP) += loop.o @@ -19,7 +18,9 @@ obj-$(CONFIG_BLK_DEV_XD) += xd.o obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o +obj-$(CONFIG_XILINX_SYSACE) += xsysace.o obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o +obj-$(CONFIG_SUNVDC) += sunvdc.o obj-$(CONFIG_BLK_DEV_UMEM) += umem.o obj-$(CONFIG_BLK_DEV_NBD) += nbd.o @@ -29,3 +30,5 @@ obj-$(CONFIG_VIODASD) += viodasd.o obj-$(CONFIG_BLK_DEV_SX8) += sx8.o obj-$(CONFIG_BLK_DEV_UB) += ub.o +obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o +obj-$(CONFIG_LGUEST_BLOCK) += lguest_blk.o diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c deleted file mode 100644 index e3d9152e231a..000000000000 --- a/drivers/block/acsi.c +++ /dev/null @@ -1,1825 +0,0 @@ -/* - * acsi.c -- Device driver for Atari ACSI hard disks - * - * Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> - * - * Some parts are based on hd.c by Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - * - */ - -/* - * Still to in this file: - * - If a command ends with an error status (!= 0), the following - * REQUEST SENSE commands (4 to fill the ST-DMA FIFO) are done by - * polling the _IRQ signal (not interrupt-driven). This should be - * avoided in future because it takes up a non-neglectible time in - * the interrupt service routine while interrupts are disabled. - * Maybe a timer interrupt will get lost :-( - */ - -/* - * General notes: - * - * - All ACSI devices (disks, CD-ROMs, ...) use major number 28. - * Minors are organized like it is with SCSI: The upper 4 bits - * identify the device, the lower 4 bits the partition. - * The device numbers (the upper 4 bits) are given in the same - * order as the devices are found on the bus. - * - Up to 8 LUNs are supported for each target (if CONFIG_ACSI_MULTI_LUN - * is defined), but only a total of 16 devices (due to minor - * numbers...). Note that Atari allows only a maximum of 4 targets - * (i.e. controllers, not devices) on the ACSI bus! - * - A optimizing scheme similar to SCSI scatter-gather is implemented. - * - Removable media are supported. After a medium change to device - * is reinitialized (partition check etc.). Also, if the device - * knows the PREVENT/ALLOW MEDIUM REMOVAL command, the door should - * be locked and unlocked when mounting the first or unmounting the - * last filesystem on the device. The code is untested, because I - * don't have a removable hard disk. - * - */ - -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/signal.h> -#include <linux/timer.h> -#include <linux/fs.h> -#include <linux/kernel.h> -#include <linux/genhd.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/major.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <scsi/scsi.h> /* for SCSI_IOCTL_GET_IDLUN */ -#include <scsi/scsi_ioctl.h> -#include <linux/hdreg.h> /* for HDIO_GETGEO */ -#include <linux/blkpg.h> -#include <linux/buffer_head.h> -#include <linux/blkdev.h> - -#include <asm/setup.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/uaccess.h> -#include <asm/atarihw.h> -#include <asm/atariints.h> -#include <asm/atari_acsi.h> -#include <asm/atari_stdma.h> -#include <asm/atari_stram.h> - -static void (*do_acsi)(void) = NULL; -static struct request_queue *acsi_queue; -#define QUEUE (acsi_queue) -#define CURRENT elv_next_request(acsi_queue) - -#define DEBUG -#undef DEBUG_DETECT -#undef NO_WRITE - -#define MAX_ERRORS 8 /* Max read/write errors/sector */ -#define MAX_LUN 8 /* Max LUNs per target */ -#define MAX_DEV 16 - -#define ACSI_BUFFER_SIZE (16*1024) /* "normal" ACSI buffer size */ -#define ACSI_BUFFER_MINSIZE (2048) /* min. buf size if ext. DMA */ -#define ACSI_BUFFER_SIZE_ORDER 2 /* order size for above */ -#define ACSI_BUFFER_MINSIZE_ORDER 0 /* order size for above */ -#define ACSI_BUFFER_SECTORS (ACSI_BUFFER_SIZE/512) - -#define ACSI_BUFFER_ORDER \ - (ATARIHW_PRESENT(EXTD_DMA) ? \ - ACSI_BUFFER_MINSIZE_ORDER : \ - ACSI_BUFFER_SIZE_ORDER) - -#define ACSI_TIMEOUT (4*HZ) - -/* minimum delay between two commands */ - -#define COMMAND_DELAY 500 - -typedef enum { - NONE, HARDDISK, CDROM -} ACSI_TYPE; - -struct acsi_info_struct { - ACSI_TYPE type; /* type of device */ - unsigned target; /* target number */ - unsigned lun; /* LUN in target controller */ - unsigned removable : 1; /* Flag for removable media */ - unsigned read_only : 1; /* Flag for read only devices */ - unsigned old_atari_disk : 1; /* Is an old Atari disk */ - unsigned changed : 1; /* Medium has been changed */ - unsigned long size; /* #blocks */ - int access_count; -} acsi_info[MAX_DEV]; - -/* - * SENSE KEYS - */ - -#define NO_SENSE 0x00 -#define RECOVERED_ERROR 0x01 -#define NOT_READY 0x02 -#define MEDIUM_ERROR 0x03 -#define HARDWARE_ERROR 0x04 -#define ILLEGAL_REQUEST 0x05 -#define UNIT_ATTENTION 0x06 -#define DATA_PROTECT 0x07 -#define BLANK_CHECK 0x08 -#define COPY_ABORTED 0x0a -#define ABORTED_COMMAND 0x0b -#define VOLUME_OVERFLOW 0x0d -#define MISCOMPARE 0x0e - - -/* - * DEVICE TYPES - */ - -#define TYPE_DISK 0x00 -#define TYPE_TAPE 0x01 -#define TYPE_WORM 0x04 -#define TYPE_ROM 0x05 -#define TYPE_MOD 0x07 -#define TYPE_NO_LUN 0x7f - -/* The data returned by MODE SENSE differ between the old Atari - * hard disks and SCSI disks connected to ACSI. In the following, both - * formats are defined and some macros to operate on them potably. - */ - -typedef struct { - unsigned long dummy[2]; - unsigned long sector_size; - unsigned char format_code; -#define ATARI_SENSE_FORMAT_FIX 1 -#define ATARI_SENSE_FORMAT_CHNG 2 - unsigned char cylinders_h; - unsigned char cylinders_l; - unsigned char heads; - unsigned char reduced_h; - unsigned char reduced_l; - unsigned char precomp_h; - unsigned char precomp_l; - unsigned char landing_zone; - unsigned char steprate; - unsigned char type; -#define ATARI_SENSE_TYPE_FIXCHNG_MASK 4 -#define ATARI_SENSE_TYPE_SOFTHARD_MASK 8 -#define ATARI_SENSE_TYPE_FIX 4 -#define ATARI_SENSE_TYPE_CHNG 0 -#define ATARI_SENSE_TYPE_SOFT 0 -#define ATARI_SENSE_TYPE_HARD 8 - unsigned char sectors; -} ATARI_SENSE_DATA; - -#define ATARI_CAPACITY(sd) \ - (((int)((sd).cylinders_h<<8)|(sd).cylinders_l) * \ - (sd).heads * (sd).sectors) - - -typedef struct { - unsigned char dummy1; - unsigned char medium_type; - unsigned char dummy2; - unsigned char descriptor_size; - unsigned long block_count; - unsigned long sector_size; - /* Page 0 data */ - unsigned char page_code; - unsigned char page_size; - unsigned char page_flags; - unsigned char qualifier; -} SCSI_SENSE_DATA; - -#define SCSI_CAPACITY(sd) ((sd).block_count & 0xffffff) - - -typedef union { - ATARI_SENSE_DATA atari; - SCSI_SENSE_DATA scsi; -} SENSE_DATA; - -#define SENSE_TYPE_UNKNOWN 0 -#define SENSE_TYPE_ATARI 1 -#define SENSE_TYPE_SCSI 2 - -#define SENSE_TYPE(sd) \ - (((sd).atari.dummy[0] == 8 && \ - ((sd).atari.format_code == 1 || \ - (sd).atari.format_code == 2)) ? SENSE_TYPE_ATARI : \ - ((sd).scsi.dummy1 >= 11) ? SENSE_TYPE_SCSI : \ - SENSE_TYPE_UNKNOWN) - -#define CAPACITY(sd) \ - (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ? \ - ATARI_CAPACITY((sd).atari) : \ - SCSI_CAPACITY((sd).scsi)) - -#define SECTOR_SIZE(sd) \ - (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ? \ - (sd).atari.sector_size : \ - (sd).scsi.sector_size & 0xffffff) - -/* Default size if capacity cannot be determined (1 GByte) */ -#define DEFAULT_SIZE 0x1fffff - -#define CARTRCH_STAT(aip,buf) \ - (aip->old_atari_disk ? \ - (((buf)[0] & 0x7f) == 0x28) : \ - ((((buf)[0] & 0x70) == 0x70) ? \ - (((buf)[2] & 0x0f) == 0x06) : \ - (((buf)[0] & 0x0f) == 0x06))) \ - -/* These two are also exported to other drivers that work on the ACSI bus and - * need an ST-RAM buffer. */ -char *acsi_buffer; -unsigned long phys_acsi_buffer; - -static int NDevices; - -static int CurrentNReq; -static int CurrentNSect; -static char *CurrentBuffer; - -static DEFINE_SPINLOCK(acsi_lock); - - -#define SET_TIMER() mod_timer(&acsi_timer, jiffies + ACSI_TIMEOUT) -#define CLEAR_TIMER() del_timer(&acsi_timer) - -static unsigned long STramMask; -#define STRAM_ADDR(a) (((a) & STramMask) == 0) - - - -/* ACSI commands */ - -static char tur_cmd[6] = { 0x00, 0, 0, 0, 0, 0 }; -static char modesense_cmd[6] = { 0x1a, 0, 0, 0, 24, 0 }; -static char modeselect_cmd[6] = { 0x15, 0, 0, 0, 12, 0 }; -static char inquiry_cmd[6] = { 0x12, 0, 0, 0,255, 0 }; -static char reqsense_cmd[6] = { 0x03, 0, 0, 0, 4, 0 }; -static char read_cmd[6] = { 0x08, 0, 0, 0, 0, 0 }; -static char write_cmd[6] = { 0x0a, 0, 0, 0, 0, 0 }; -static char pa_med_rem_cmd[6] = { 0x1e, 0, 0, 0, 0, 0 }; - -#define CMDSET_TARG_LUN(cmd,targ,lun) \ - do { \ - cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5; \ - cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5; \ - } while(0) - -#define CMDSET_BLOCK(cmd,blk) \ - do { \ - unsigned long __blk = (blk); \ - cmd[3] = __blk; __blk >>= 8; \ - cmd[2] = __blk; __blk >>= 8; \ - cmd[1] = (cmd[1] & 0xe0) | (__blk & 0x1f); \ - } while(0) - -#define CMDSET_LEN(cmd,len) \ - do { \ - cmd[4] = (len); \ - } while(0) - -/* ACSI errors (from REQUEST SENSE); There are two tables, one for the - * old Atari disks and one for SCSI on ACSI disks. - */ - -struct acsi_error { - unsigned char code; - const char *text; -} atari_acsi_errors[] = { - { 0x00, "No error (??)" }, - { 0x01, "No index pulses" }, - { 0x02, "Seek not complete" }, - { 0x03, "Write fault" }, - { 0x04, "Drive not ready" }, - { 0x06, "No Track 00 signal" }, - { 0x10, "ECC error in ID field" }, - { 0x11, "Uncorrectable data error" }, - { 0x12, "ID field address mark not found" }, - { 0x13, "Data field address mark not found" }, - { 0x14, "Record not found" }, - { 0x15, "Seek error" }, - { 0x18, "Data check in no retry mode" }, - { 0x19, "ECC error during verify" }, - { 0x1a, "Access to bad block" }, - { 0x1c, "Unformatted or bad format" }, - { 0x20, "Invalid command" }, - { 0x21, "Invalid block address" }, - { 0x23, "Volume overflow" }, - { 0x24, "Invalid argument" }, - { 0x25, "Invalid drive number" }, - { 0x26, "Byte zero parity check" }, - { 0x28, "Cartride changed" }, - { 0x2c, "Error count overflow" }, - { 0x30, "Controller selftest failed" } -}, - - scsi_acsi_errors[] = { - { 0x00, "No error (??)" }, - { 0x01, "Recovered error" }, - { 0x02, "Drive not ready" }, - { 0x03, "Uncorrectable medium error" }, - { 0x04, "Hardware error" }, - { 0x05, "Illegal request" }, - { 0x06, "Unit attention (Reset or cartridge changed)" }, - { 0x07, "Data protection" }, - { 0x08, "Blank check" }, - { 0x0b, "Aborted Command" }, - { 0x0d, "Volume overflow" } -}; - - - -/***************************** Prototypes *****************************/ - -static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int - rwflag, int enable); -static int acsi_reqsense( char *buffer, int targ, int lun); -static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip); -static irqreturn_t acsi_interrupt (int irq, void *data); -static void unexpected_acsi_interrupt( void ); -static void bad_rw_intr( void ); -static void read_intr( void ); -static void write_intr( void); -static void acsi_times_out( unsigned long dummy ); -static void copy_to_acsibuffer( void ); -static void copy_from_acsibuffer( void ); -static void do_end_requests( void ); -static void do_acsi_request( request_queue_t * ); -static void redo_acsi_request( void ); -static int acsi_ioctl( struct inode *inode, struct file *file, unsigned int - cmd, unsigned long arg ); -static int acsi_open( struct inode * inode, struct file * filp ); -static int acsi_release( struct inode * inode, struct file * file ); -static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag ); -static int acsi_change_blk_size( int target, int lun); -static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd ); -static int acsi_revalidate (struct gendisk *disk); - -/************************* End of Prototypes **************************/ - - -DEFINE_TIMER(acsi_timer, acsi_times_out, 0, 0); - - -#ifdef CONFIG_ATARI_SLM - -extern int attach_slm( int target, int lun ); -extern int slm_init( void ); - -#endif - - - -/*********************************************************************** - * - * ACSI primitives - * - **********************************************************************/ - - -/* - * The following two functions wait for _IRQ to become Low or High, - * resp., with a timeout. The 'timeout' parameter is in jiffies - * (10ms). - * If the functions are called with timer interrupts on (int level < - * 6), the timeout is based on the 'jiffies' variable to provide exact - * timeouts for device probing etc. - * If interrupts are disabled, the number of tries is based on the - * 'loops_per_jiffy' variable. A rough estimation is sufficient here... - */ - -#define INT_LEVEL \ - ({ unsigned __sr; \ - __asm__ __volatile__ ( "movew %/sr,%0" : "=dm" (__sr) ); \ - (__sr >> 8) & 7; \ - }) - -int acsi_wait_for_IRQ( unsigned timeout ) - -{ - if (INT_LEVEL < 6) { - unsigned long maxjif = jiffies + timeout; - while (time_before(jiffies, maxjif)) - if (!(mfp.par_dt_reg & 0x20)) return( 1 ); - } - else { - long tries = loops_per_jiffy / 8 * timeout; - while( --tries >= 0 ) - if (!(mfp.par_dt_reg & 0x20)) return( 1 ); - } - return( 0 ); /* timeout! */ -} - - -int acsi_wait_for_noIRQ( unsigned timeout ) - -{ - if (INT_LEVEL < 6) { - unsigned long maxjif = jiffies + timeout; - while (time_before(jiffies, maxjif)) - if (mfp.par_dt_reg & 0x20) return( 1 ); - } - else { - long tries = loops_per_jiffy * timeout / 8; - while( tries-- >= 0 ) - if (mfp.par_dt_reg & 0x20) return( 1 ); - } - return( 0 ); /* timeout! */ -} - -static struct timeval start_time; - -void -acsi_delay_start(void) -{ - do_gettimeofday(&start_time); -} - -/* wait from acsi_delay_start to now usec (<1E6) usec */ - -void -acsi_delay_end(long usec) -{ - struct timeval end_time; - long deltau,deltas; - do_gettimeofday(&end_time); - deltau=end_time.tv_usec - start_time.tv_usec; - deltas=end_time.tv_sec - start_time.tv_sec; - if (deltas > 1 || deltas < 0) - return; - if (deltas > 0) - deltau += 1000*1000; - if (deltau >= usec) - return; - udelay(usec-deltau); -} - -/* acsicmd_dma() sends an ACSI command and sets up the DMA to transfer - * 'blocks' blocks of 512 bytes from/to 'buffer'. - * Because the _IRQ signal is used for handshaking the command bytes, - * the ACSI interrupt has to be disabled in this function. If the end - * of the operation should be signalled by a real interrupt, it has to be - * reenabled afterwards. - */ - -static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int rwflag, int enable) - -{ unsigned long flags, paddr; - int i; - -#ifdef NO_WRITE - if (rwflag || *cmd == 0x0a) { - printk( "ACSI: Write commands disabled!\n" ); - return( 0 ); - } -#endif - - rwflag = rwflag ? 0x100 : 0; - paddr = virt_to_phys( buffer ); - - acsi_delay_end(COMMAND_DELAY); - DISABLE_IRQ(); - - local_irq_save(flags); - /* Low on A1 */ - dma_wd.dma_mode_status = 0x88 | rwflag; - MFPDELAY(); - - /* set DMA address */ - dma_wd.dma_lo = (unsigned char)paddr; - paddr >>= 8; - MFPDELAY(); - dma_wd.dma_md = (unsigned char)paddr; - paddr >>= 8; - MFPDELAY(); - if (ATARIHW_PRESENT(EXTD_DMA)) - st_dma_ext_dmahi = (unsigned short)paddr; - else - dma_wd.dma_hi = (unsigned char)paddr; - MFPDELAY(); - local_irq_restore(flags); - - /* send the command bytes except the last */ - for( i = 0; i < 5; ++i ) { - DMA_LONG_WRITE( *cmd++, 0x8a | rwflag ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */ - } - - /* Clear FIFO and switch DMA to correct direction */ - dma_wd.dma_mode_status = 0x92 | (rwflag ^ 0x100); - MFPDELAY(); - dma_wd.dma_mode_status = 0x92 | rwflag; - MFPDELAY(); - - /* How many sectors for DMA */ - dma_wd.fdc_acces_seccount = blocks; - MFPDELAY(); - - /* send last command byte */ - dma_wd.dma_mode_status = 0x8a | rwflag; - MFPDELAY(); - DMA_LONG_WRITE( *cmd++, 0x0a | rwflag ); - if (enable) - ENABLE_IRQ(); - udelay(80); - - return( 1 ); -} - - -/* - * acsicmd_nodma() sends an ACSI command that requires no DMA. - */ - -int acsicmd_nodma( const char *cmd, int enable) - -{ int i; - - acsi_delay_end(COMMAND_DELAY); - DISABLE_IRQ(); - - /* send first command byte */ - dma_wd.dma_mode_status = 0x88; - MFPDELAY(); - DMA_LONG_WRITE( *cmd++, 0x8a ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */ - - /* send the intermediate command bytes */ - for( i = 0; i < 4; ++i ) { - DMA_LONG_WRITE( *cmd++, 0x8a ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */ - } - - /* send last command byte */ - DMA_LONG_WRITE( *cmd++, 0x0a ); - if (enable) - ENABLE_IRQ(); - udelay(80); - - return( 1 ); - /* Note that the ACSI interrupt is still disabled after this - * function. If you want to get the IRQ delivered, enable it manually! - */ -} - - -static int acsi_reqsense( char *buffer, int targ, int lun) - -{ - CMDSET_TARG_LUN( reqsense_cmd, targ, lun); - if (!acsicmd_dma( reqsense_cmd, buffer, 1, 0, 0 )) return( 0 ); - if (!acsi_wait_for_IRQ( 10 )) return( 0 ); - acsi_getstatus(); - if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 ); - if (!acsi_wait_for_IRQ( 10 )) return( 0 ); - acsi_getstatus(); - if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 ); - if (!acsi_wait_for_IRQ( 10 )) return( 0 ); - acsi_getstatus(); - if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 ); - if (!acsi_wait_for_IRQ( 10 )) return( 0 ); - acsi_getstatus(); - dma_cache_maintenance( virt_to_phys(buffer), 16, 0 ); - - return( 1 ); -} - - -/* - * ACSI status phase: get the status byte from the bus - * - * I've seen several times that a 0xff status is read, propably due to - * a timing error. In this case, the procedure is repeated after the - * next _IRQ edge. - */ - -int acsi_getstatus( void ) - -{ int status; - - DISABLE_IRQ(); - for(;;) { - if (!acsi_wait_for_IRQ( 100 )) { - acsi_delay_start(); - return( -1 ); - } - dma_wd.dma_mode_status = 0x8a; - MFPDELAY(); - status = dma_wd.fdc_acces_seccount; - if (status != 0xff) break; -#ifdef DEBUG - printk("ACSI: skipping 0xff status byte\n" ); -#endif - udelay(40); - acsi_wait_for_noIRQ( 20 ); - } - dma_wd.dma_mode_status = 0x80; - udelay(40); - acsi_wait_for_noIRQ( 20 ); - - acsi_delay_start(); - return( status & 0x1f ); /* mask of the device# */ -} - - -#if (defined(CONFIG_ATARI_SLM) || defined(CONFIG_ATARI_SLM_MODULE)) - -/* Receive data in an extended status phase. Needed by SLM printer. */ - -int acsi_extstatus( char *buffer, int cnt ) - -{ int status; - - DISABLE_IRQ(); - udelay(80); - while( cnt-- > 0 ) { - if (!acsi_wait_for_IRQ( 40 )) return( 0 ); - dma_wd.dma_mode_status = 0x8a; - MFPDELAY(); - status = dma_wd.fdc_acces_seccount; - MFPDELAY(); - *buffer++ = status & 0xff; - udelay(40); - } - return( 1 ); -} - - -/* Finish an extended status phase */ - -void acsi_end_extstatus( void ) - -{ - dma_wd.dma_mode_status = 0x80; - udelay(40); - acsi_wait_for_noIRQ( 20 ); - acsi_delay_start(); -} - - -/* Send data in an extended command phase */ - -int acsi_extcmd( unsigned char *buffer, int cnt ) - -{ - while( cnt-- > 0 ) { - DMA_LONG_WRITE( *buffer++, 0x8a ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */ - } - return( 1 ); -} - -#endif - - -static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip) - -{ int atari_err, i, errcode; - struct acsi_error *arr; - - atari_err = aip->old_atari_disk; - if (atari_err) - errcode = errblk[0] & 0x7f; - else - if ((errblk[0] & 0x70) == 0x70) - errcode = errblk[2] & 0x0f; - else - errcode = errblk[0] & 0x0f; - - printk( KERN_ERR "ACSI error 0x%02x", errcode ); - - if (errblk[0] & 0x80) - printk( " for sector %d", - ((errblk[1] & 0x1f) << 16) | - (errblk[2] << 8) | errblk[0] ); - - arr = atari_err ? atari_acsi_errors : scsi_acsi_errors; - i = atari_err ? sizeof(atari_acsi_errors)/sizeof(*atari_acsi_errors) : - sizeof(scsi_acsi_errors)/sizeof(*scsi_acsi_errors); - - for( --i; i >= 0; --i ) - if (arr[i].code == errcode) break; - if (i >= 0) - printk( ": %s\n", arr[i].text ); -} - -/******************************************************************* - * - * ACSI interrupt routine - * Test, if this is a ACSI interrupt and call the irq handler - * Otherwise ignore this interrupt. - * - *******************************************************************/ - -static irqreturn_t acsi_interrupt(int irq, void *data ) - -{ void (*acsi_irq_handler)(void) = do_acsi; - - do_acsi = NULL; - CLEAR_TIMER(); - - if (!acsi_irq_handler) - acsi_irq_handler = unexpected_acsi_interrupt; - acsi_irq_handler(); - return IRQ_HANDLED; -} - - -/****************************************************************** - * - * The Interrupt handlers - * - *******************************************************************/ - - -static void unexpected_acsi_interrupt( void ) - -{ - printk( KERN_WARNING "Unexpected ACSI interrupt\n" ); -} - - -/* This function is called in case of errors. Because we cannot reset - * the ACSI bus or a single device, there is no other choice than - * retrying several times :-( - */ - -static void bad_rw_intr( void ) - -{ - if (!CURRENT) - return; - - if (++CURRENT->errors >= MAX_ERRORS) - end_request(CURRENT, 0); - /* Otherwise just retry */ -} - - -static void read_intr( void ) - -{ int status; - - status = acsi_getstatus(); - if (status != 0) { - struct gendisk *disk = CURRENT->rq_disk; - struct acsi_info_struct *aip = disk->private_data; - printk(KERN_ERR "%s: ", disk->disk_name); - if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun)) - printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status ); - else { - acsi_print_error(acsi_buffer, aip); - if (CARTRCH_STAT(aip, acsi_buffer)) - aip->changed = 1; - } - ENABLE_IRQ(); - bad_rw_intr(); - redo_acsi_request(); - return; - } - - dma_cache_maintenance( virt_to_phys(CurrentBuffer), CurrentNSect*512, 0 ); - if (CurrentBuffer == acsi_buffer) - copy_from_acsibuffer(); - - do_end_requests(); - redo_acsi_request(); -} - - -static void write_intr(void) - -{ int status; - - status = acsi_getstatus(); - if (status != 0) { - struct gendisk *disk = CURRENT->rq_disk; - struct acsi_info_struct *aip = disk->private_data; - printk( KERN_ERR "%s: ", disk->disk_name); - if (!acsi_reqsense( acsi_buffer, aip->target, aip->lun)) - printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status ); - else { - acsi_print_error(acsi_buffer, aip); - if (CARTRCH_STAT(aip, acsi_buffer)) - aip->changed = 1; - } - bad_rw_intr(); - redo_acsi_request(); - return; - } - - do_end_requests(); - redo_acsi_request(); -} - - -static void acsi_times_out( unsigned long dummy ) - -{ - DISABLE_IRQ(); - if (!do_acsi) return; - - do_acsi = NULL; - printk( KERN_ERR "ACSI timeout\n" ); - if (!CURRENT) - return; - if (++CURRENT->errors >= MAX_ERRORS) { -#ifdef DEBUG - printk( KERN_ERR "ACSI: too many errors.\n" ); -#endif - end_request(CURRENT, 0); - } - - redo_acsi_request(); -} - - - -/*********************************************************************** - * - * Scatter-gather utility functions - * - ***********************************************************************/ - - -static void copy_to_acsibuffer( void ) - -{ int i; - char *src, *dst; - struct buffer_head *bh; - - src = CURRENT->buffer; - dst = acsi_buffer; - bh = CURRENT->bh; - - if (!bh) - memcpy( dst, src, CurrentNSect*512 ); - else - for( i = 0; i < CurrentNReq; ++i ) { - memcpy( dst, src, bh->b_size ); - dst += bh->b_size; - if ((bh = bh->b_reqnext)) - src = bh->b_data; - } -} - - -static void copy_from_acsibuffer( void ) - -{ int i; - char *src, *dst; - struct buffer_head *bh; - - dst = CURRENT->buffer; - src = acsi_buffer; - bh = CURRENT->bh; - - if (!bh) - memcpy( dst, src, CurrentNSect*512 ); - else - for( i = 0; i < CurrentNReq; ++i ) { - memcpy( dst, src, bh->b_size ); - src += bh->b_size; - if ((bh = bh->b_reqnext)) - dst = bh->b_data; - } -} - - -static void do_end_requests( void ) - -{ int i, n; - - if (!CURRENT->bh) { - CURRENT->nr_sectors -= CurrentNSect; - CURRENT->current_nr_sectors -= CurrentNSect; - CURRENT->sector += CurrentNSect; - if (CURRENT->nr_sectors == 0) - end_request(CURRENT, 1); - } - else { - for( i = 0; i < CurrentNReq; ++i ) { - n = CURRENT->bh->b_size >> 9; - CURRENT->nr_sectors -= n; - CURRENT->current_nr_sectors -= n; - CURRENT->sector += n; - end_request(CURRENT, 1); - } - } -} - - - - -/*********************************************************************** - * - * do_acsi_request and friends - * - ***********************************************************************/ - -static void do_acsi_request( request_queue_t * q ) - -{ - stdma_lock( acsi_interrupt, NULL ); - redo_acsi_request(); -} - - -static void redo_acsi_request( void ) -{ - unsigned block, target, lun, nsect; - char *buffer; - unsigned long pbuffer; - struct buffer_head *bh; - struct gendisk *disk; - struct acsi_info_struct *aip; - - repeat: - CLEAR_TIMER(); - - if (do_acsi) - return; - - if (!CURRENT) { - do_acsi = NULL; - ENABLE_IRQ(); - stdma_release(); - return; - } - - disk = CURRENT->rq_disk; - aip = disk->private_data; - if (CURRENT->bh) { - if (!CURRENT->bh && !buffer_locked(CURRENT->bh)) - panic("ACSI: block not locked"); - } - - block = CURRENT->sector; - if (block+CURRENT->nr_sectors >= get_capacity(disk)) { -#ifdef DEBUG - printk( "%s: attempted access for blocks %d...%ld past end of device at block %ld.\n", - disk->disk_name, - block, block + CURRENT->nr_sectors - 1, - get_capacity(disk)); -#endif - end_request(CURRENT, 0); - goto repeat; - } - if (aip->changed) { - printk( KERN_NOTICE "%s: request denied because cartridge has " - "been changed.\n", disk->disk_name); - end_request(CURRENT, 0); - goto repeat; - } - - target = aip->target; - lun = aip->lun; - - /* Find out how many sectors should be transferred from/to - * consecutive buffers and thus can be done with a single command. - */ - buffer = CURRENT->buffer; - pbuffer = virt_to_phys(buffer); - nsect = CURRENT->current_nr_sectors; - CurrentNReq = 1; - - if ((bh = CURRENT->bh) && bh != CURRENT->bhtail) { - if (!STRAM_ADDR(pbuffer)) { - /* If transfer is done via the ACSI buffer anyway, we can - * assemble as much bh's as fit in the buffer. - */ - while( (bh = bh->b_reqnext) ) { - if (nsect + (bh->b_size>>9) > ACSI_BUFFER_SECTORS) break; - nsect += bh->b_size >> 9; - ++CurrentNReq; - if (bh == CURRENT->bhtail) break; - } - buffer = acsi_buffer; - pbuffer = phys_acsi_buffer; - } - else { - unsigned long pendadr, pnewadr; - pendadr = pbuffer + nsect*512; - while( (bh = bh->b_reqnext) ) { - pnewadr = virt_to_phys(bh->b_data); - if (!STRAM_ADDR(pnewadr) || pendadr != pnewadr) break; - nsect += bh->b_size >> 9; - pendadr = pnewadr + bh->b_size; - ++CurrentNReq; - if (bh == CURRENT->bhtail) break; - } - } - } - else { - if (!STRAM_ADDR(pbuffer)) { - buffer = acsi_buffer; - pbuffer = phys_acsi_buffer; - if (nsect > ACSI_BUFFER_SECTORS) - nsect = ACSI_BUFFER_SECTORS; - } - } - CurrentBuffer = buffer; - CurrentNSect = nsect; - - if (rq_data_dir(CURRENT) == WRITE) { - CMDSET_TARG_LUN( write_cmd, target, lun ); - CMDSET_BLOCK( write_cmd, block ); - CMDSET_LEN( write_cmd, nsect ); - if (buffer == acsi_buffer) - copy_to_acsibuffer(); - dma_cache_maintenance( pbuffer, nsect*512, 1 ); - do_acsi = write_intr; - if (!acsicmd_dma( write_cmd, buffer, nsect, 1, 1)) { - do_acsi = NULL; - printk( KERN_ERR "ACSI (write): Timeout in command block\n" ); - bad_rw_intr(); - goto repeat; - } - SET_TIMER(); - return; - } - if (rq_data_dir(CURRENT) == READ) { - CMDSET_TARG_LUN( read_cmd, target, lun ); - CMDSET_BLOCK( read_cmd, block ); - CMDSET_LEN( read_cmd, nsect ); - do_acsi = read_intr; - if (!acsicmd_dma( read_cmd, buffer, nsect, 0, 1)) { - do_acsi = NULL; - printk( KERN_ERR "ACSI (read): Timeout in command block\n" ); - bad_rw_intr(); - goto repeat; - } - SET_TIMER(); - return; - } - panic("unknown ACSI command"); -} - - - -/*********************************************************************** - * - * Misc functions: ioctl, open, release, check_change, ... - * - ***********************************************************************/ - -static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct acsi_info_struct *aip = bdev->bd_disk->private_data; - - /* - * Just fake some geometry here, it's nonsense anyway - * To make it easy, use Adaptec's usual 64/32 mapping - */ - geo->heads = 64; - geo->sectors = 32; - geo->cylinders = aip->size >> 11; - return 0; -} - -static int acsi_ioctl( struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg ) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct acsi_info_struct *aip = disk->private_data; - switch (cmd) { - case SCSI_IOCTL_GET_IDLUN: - /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */ - put_user( aip->target | (aip->lun << 8), - &((Scsi_Idlun *) arg)->dev_id ); - put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id ); - return 0; - default: - return -EINVAL; - } -} - - -/* - * Open a device, check for read-only and lock the medium if it is - * removable. - * - * Changes by Martin Rogge, 9th Aug 1995: - * Check whether check_disk_change (and therefore revalidate_acsidisk) - * was successful. They fail when there is no medium in the drive. - * - * The problem of media being changed during an operation can be - * ignored because of the prevent_removal code. - * - * Added check for the validity of the device number. - * - */ - -static int acsi_open( struct inode * inode, struct file * filp ) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct acsi_info_struct *aip = disk->private_data; - - if (aip->access_count == 0 && aip->removable) { -#if 0 - aip->changed = 1; /* safety first */ -#endif - check_disk_change( inode->i_bdev ); - if (aip->changed) /* revalidate was not successful (no medium) */ - return -ENXIO; - acsi_prevent_removal(aip, 1); - } - aip->access_count++; - - if (filp && filp->f_mode) { - check_disk_change( inode->i_bdev ); - if (filp->f_mode & 2) { - if (aip->read_only) { - acsi_release( inode, filp ); - return -EROFS; - } - } - } - - return 0; -} - -/* - * Releasing a block device means we sync() it, so that it can safely - * be forgotten about... - */ - -static int acsi_release( struct inode * inode, struct file * file ) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct acsi_info_struct *aip = disk->private_data; - if (--aip->access_count == 0 && aip->removable) - acsi_prevent_removal(aip, 0); - return( 0 ); -} - -/* - * Prevent or allow a media change for removable devices. - */ - -static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag) -{ - stdma_lock( NULL, NULL ); - - CMDSET_TARG_LUN(pa_med_rem_cmd, aip->target, aip->lun); - CMDSET_LEN( pa_med_rem_cmd, flag ); - - if (acsicmd_nodma(pa_med_rem_cmd, 0) && acsi_wait_for_IRQ(3*HZ)) - acsi_getstatus(); - /* Do not report errors -- some devices may not know this command. */ - - ENABLE_IRQ(); - stdma_release(); -} - -static int acsi_media_change(struct gendisk *disk) -{ - struct acsi_info_struct *aip = disk->private_data; - - if (!aip->removable) - return 0; - - if (aip->changed) - /* We can be sure that the medium has been changed -- REQUEST - * SENSE has reported this earlier. - */ - return 1; - - /* If the flag isn't set, make a test by reading block 0. - * If errors happen, it seems to be better to say "changed"... - */ - stdma_lock( NULL, NULL ); - CMDSET_TARG_LUN(read_cmd, aip->target, aip->lun); - CMDSET_BLOCK( read_cmd, 0 ); - CMDSET_LEN( read_cmd, 1 ); - if (acsicmd_dma(read_cmd, acsi_buffer, 1, 0, 0) && - acsi_wait_for_IRQ(3*HZ)) { - if (acsi_getstatus()) { - if (acsi_reqsense(acsi_buffer, aip->target, aip->lun)) { - if (CARTRCH_STAT(aip, acsi_buffer)) - aip->changed = 1; - } - else { - printk( KERN_ERR "%s: REQUEST SENSE failed in test for " - "medium change; assuming a change\n", disk->disk_name ); - aip->changed = 1; - } - } - } - else { - printk( KERN_ERR "%s: Test for medium changed timed out; " - "assuming a change\n", disk->disk_name); - aip->changed = 1; - } - ENABLE_IRQ(); - stdma_release(); - - /* Now, after reading a block, the changed status is surely valid. */ - return aip->changed; -} - - -static int acsi_change_blk_size( int target, int lun) - -{ int i; - - for (i=0; i<12; i++) - acsi_buffer[i] = 0; - - acsi_buffer[3] = 8; - acsi_buffer[10] = 2; - CMDSET_TARG_LUN( modeselect_cmd, target, lun); - - if (!acsicmd_dma( modeselect_cmd, acsi_buffer, 1,1,0) || - !acsi_wait_for_IRQ( 3*HZ ) || - acsi_getstatus() != 0 ) { - return(0); - } - return(1); -} - - -static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd ) - -{ - int page; - - CMDSET_TARG_LUN( modesense_cmd, target, lun ); - for (page=0; page<4; page++) { - modesense_cmd[2] = page; - if (!acsicmd_dma( modesense_cmd, acsi_buffer, 1, 0, 0 ) || - !acsi_wait_for_IRQ( 3*HZ ) || - acsi_getstatus()) - continue; - - /* read twice to jump over the second 16-byte border! */ - udelay(300); - if (acsi_wait_for_noIRQ( 20 ) && - acsicmd_nodma( modesense_cmd, 0 ) && - acsi_wait_for_IRQ( 3*HZ ) && - acsi_getstatus() == 0) - break; - } - if (page == 4) { - return(0); - } - - dma_cache_maintenance( phys_acsi_buffer, sizeof(SENSE_DATA), 0 ); - *sd = *(SENSE_DATA *)acsi_buffer; - - /* Validity check, depending on type of data */ - - switch( SENSE_TYPE(*sd) ) { - - case SENSE_TYPE_ATARI: - if (CAPACITY(*sd) == 0) - goto invalid_sense; - break; - - case SENSE_TYPE_SCSI: - if (sd->scsi.descriptor_size != 8) - goto invalid_sense; - break; - - case SENSE_TYPE_UNKNOWN: - - printk( KERN_ERR "ACSI target %d, lun %d: Cannot interpret " - "sense data\n", target, lun ); - - invalid_sense: - -#ifdef DEBUG - { int i; - printk( "Mode sense data for ACSI target %d, lun %d seem not valid:", - target, lun ); - for( i = 0; i < sizeof(SENSE_DATA); ++i ) - printk( "%02x ", (unsigned char)acsi_buffer[i] ); - printk( "\n" ); - } -#endif - return( 0 ); - } - - return( 1 ); -} - - - -/******************************************************************* - * - * Initialization - * - ********************************************************************/ - - -extern struct block_device_operations acsi_fops; - -static struct gendisk *acsi_gendisk[MAX_DEV]; - -#define MAX_SCSI_DEVICE_CODE 10 - -static const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = -{ - "Direct-Access ", - "Sequential-Access", - "Printer ", - "Processor ", - "WORM ", - "CD-ROM ", - "Scanner ", - "Optical Device ", - "Medium Changer ", - "Communications " -}; - -static void print_inquiry(unsigned char *data) -{ - int i; - - printk(KERN_INFO " Vendor: "); - for (i = 8; i < 16; i++) - { - if (data[i] >= 0x20 && i < data[4] + 5) - printk("%c", data[i]); - else - printk(" "); - } - - printk(" Model: "); - for (i = 16; i < 32; i++) - { - if (data[i] >= 0x20 && i < data[4] + 5) - printk("%c", data[i]); - else - printk(" "); - } - - printk(" Rev: "); - for (i = 32; i < 36; i++) - { - if (data[i] >= 0x20 && i < data[4] + 5) - printk("%c", data[i]); - else - printk(" "); - } - - printk("\n"); - - i = data[0] & 0x1f; - - printk(KERN_INFO " Type: %s ", (i < MAX_SCSI_DEVICE_CODE - ? scsi_device_types[i] - : "Unknown ")); - printk(" ANSI SCSI revision: %02x", data[2] & 0x07); - if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1) - printk(" CCS\n"); - else - printk("\n"); -} - - -/* - * Changes by Martin Rogge, 9th Aug 1995: - * acsi_devinit has been taken out of acsi_geninit, because it needs - * to be called from revalidate_acsidisk. The result of request sense - * is now checked for DRIVE NOT READY. - * - * The structure *aip is only valid when acsi_devinit returns - * DEV_SUPPORTED. - * - */ - -#define DEV_NONE 0 -#define DEV_UNKNOWN 1 -#define DEV_SUPPORTED 2 -#define DEV_SLM 3 - -static int acsi_devinit(struct acsi_info_struct *aip) -{ - int status, got_inquiry; - SENSE_DATA sense; - unsigned char reqsense, extsense; - - /*****************************************************************/ - /* Do a TEST UNIT READY command to test the presence of a device */ - /*****************************************************************/ - - CMDSET_TARG_LUN(tur_cmd, aip->target, aip->lun); - if (!acsicmd_nodma(tur_cmd, 0)) { - /* timed out -> no device here */ -#ifdef DEBUG_DETECT - printk("target %d lun %d: timeout\n", aip->target, aip->lun); -#endif - return DEV_NONE; - } - - /*************************/ - /* Read the ACSI status. */ - /*************************/ - - status = acsi_getstatus(); - if (status) { - if (status == 0x12) { - /* The SLM printer should be the only device that - * responds with the error code in the status byte. In - * correct status bytes, bit 4 is never set. - */ - printk( KERN_INFO "Detected SLM printer at id %d lun %d\n", - aip->target, aip->lun); - return DEV_SLM; - } - /* ignore CHECK CONDITION, since some devices send a - UNIT ATTENTION */ - if ((status & 0x1e) != 0x2) { -#ifdef DEBUG_DETECT - printk("target %d lun %d: status %d\n", - aip->target, aip->lun, status); -#endif - return DEV_UNKNOWN; - } - } - - /*******************************/ - /* Do a REQUEST SENSE command. */ - /*******************************/ - - if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun)) { - printk( KERN_WARNING "acsi_reqsense failed\n"); - acsi_buffer[0] = 0; - acsi_buffer[2] = UNIT_ATTENTION; - } - reqsense = acsi_buffer[0]; - extsense = acsi_buffer[2] & 0xf; - if (status) { - if ((reqsense & 0x70) == 0x70) { /* extended sense */ - if (extsense != UNIT_ATTENTION && - extsense != NOT_READY) { -#ifdef DEBUG_DETECT - printk("target %d lun %d: extended sense %d\n", - aip->target, aip->lun, extsense); -#endif - return DEV_UNKNOWN; - } - } - else { - if (reqsense & 0x7f) { -#ifdef DEBUG_DETECT - printk("target %d lun %d: sense %d\n", - aip->target, aip->lun, reqsense); -#endif - return DEV_UNKNOWN; - } - } - } - else - if (reqsense == 0x4) { /* SH204 Bug workaround */ -#ifdef DEBUG_DETECT - printk("target %d lun %d status=0 sense=4\n", - aip->target, aip->lun); -#endif - return DEV_UNKNOWN; - } - - /***********************************************************/ - /* Do an INQUIRY command to get more infos on this device. */ - /***********************************************************/ - - /* Assume default values */ - aip->removable = 1; - aip->read_only = 0; - aip->old_atari_disk = 0; - aip->changed = (extsense == NOT_READY); /* medium inserted? */ - aip->size = DEFAULT_SIZE; - got_inquiry = 0; - /* Fake inquiry result for old atari disks */ - memcpy(acsi_buffer, "\000\000\001\000 Adaptec 40xx" - " ", 40); - CMDSET_TARG_LUN(inquiry_cmd, aip->target, aip->lun); - if (acsicmd_dma(inquiry_cmd, acsi_buffer, 1, 0, 0) && - acsi_getstatus() == 0) { - acsicmd_nodma(inquiry_cmd, 0); - acsi_getstatus(); - dma_cache_maintenance( phys_acsi_buffer, 256, 0 ); - got_inquiry = 1; - aip->removable = !!(acsi_buffer[1] & 0x80); - } - if (aip->type == NONE) /* only at boot time */ - print_inquiry(acsi_buffer); - switch(acsi_buffer[0]) { - case TYPE_DISK: - aip->type = HARDDISK; - break; - case TYPE_ROM: - aip->type = CDROM; - aip->read_only = 1; - break; - default: - return DEV_UNKNOWN; - } - /****************************/ - /* Do a MODE SENSE command. */ - /****************************/ - - if (!acsi_mode_sense(aip->target, aip->lun, &sense)) { - printk( KERN_WARNING "No mode sense data.\n" ); - return DEV_UNKNOWN; - } - if ((SECTOR_SIZE(sense) != 512) && - ((aip->type != CDROM) || - !acsi_change_blk_size(aip->target, aip->lun) || - !acsi_mode_sense(aip->target, aip->lun, &sense) || - (SECTOR_SIZE(sense) != 512))) { - printk( KERN_WARNING "Sector size != 512 not supported.\n" ); - return DEV_UNKNOWN; - } - /* There are disks out there that claim to have 0 sectors... */ - if (CAPACITY(sense)) - aip->size = CAPACITY(sense); /* else keep DEFAULT_SIZE */ - if (!got_inquiry && SENSE_TYPE(sense) == SENSE_TYPE_ATARI) { - /* If INQUIRY failed and the sense data suggest an old - * Atari disk (SH20x, Megafile), the disk is not removable - */ - aip->removable = 0; - aip->old_atari_disk = 1; - } - - /******************/ - /* We've done it. */ - /******************/ - - return DEV_SUPPORTED; -} - -EXPORT_SYMBOL(acsi_delay_start); -EXPORT_SYMBOL(acsi_delay_end); -EXPORT_SYMBOL(acsi_wait_for_IRQ); -EXPORT_SYMBOL(acsi_wait_for_noIRQ); -EXPORT_SYMBOL(acsicmd_nodma); -EXPORT_SYMBOL(acsi_getstatus); -EXPORT_SYMBOL(acsi_buffer); -EXPORT_SYMBOL(phys_acsi_buffer); - -#ifdef CONFIG_ATARI_SLM_MODULE -void acsi_attach_SLMs( int (*attach_func)( int, int ) ); - -EXPORT_SYMBOL(acsi_extstatus); -EXPORT_SYMBOL(acsi_end_extstatus); -EXPORT_SYMBOL(acsi_extcmd); -EXPORT_SYMBOL(acsi_attach_SLMs); - -/* to remember IDs of SLM devices, SLM module is loaded later - * (index is target#, contents is lun#, -1 means "no SLM") */ -int SLM_devices[8]; -#endif - -static struct block_device_operations acsi_fops = { - .owner = THIS_MODULE, - .open = acsi_open, - .release = acsi_release, - .ioctl = acsi_ioctl, - .getgeo = acsi_getgeo, - .media_changed = acsi_media_change, - .revalidate_disk= acsi_revalidate, -}; - -#ifdef CONFIG_ATARI_SLM_MODULE -/* call attach_slm() for each device that is a printer; needed for init of SLM - * driver as a module, since it's not yet present if acsi.c is inited and thus - * the bus gets scanned. */ -void acsi_attach_SLMs( int (*attach_func)( int, int ) ) -{ - int i, n = 0; - - for( i = 0; i < 8; ++i ) - if (SLM_devices[i] >= 0) - n += (*attach_func)( i, SLM_devices[i] ); - printk( KERN_INFO "Found %d SLM printer(s) total.\n", n ); -} -#endif /* CONFIG_ATARI_SLM_MODULE */ - - -int acsi_init( void ) -{ - int err = 0; - int i, target, lun; - struct acsi_info_struct *aip; -#ifdef CONFIG_ATARI_SLM - int n_slm = 0; -#endif - if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ACSI)) - return 0; - if (register_blkdev(ACSI_MAJOR, "ad")) { - err = -EBUSY; - goto out1; - } - if (!(acsi_buffer = - (char *)atari_stram_alloc(ACSI_BUFFER_SIZE, "acsi"))) { - err = -ENOMEM; - printk( KERN_ERR "Unable to get ACSI ST-Ram buffer.\n" ); - goto out2; - } - phys_acsi_buffer = virt_to_phys( acsi_buffer ); - STramMask = ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000 : 0xff000000; - - acsi_queue = blk_init_queue(do_acsi_request, &acsi_lock); - if (!acsi_queue) { - err = -ENOMEM; - goto out2a; - } -#ifdef CONFIG_ATARI_SLM - err = slm_init(); -#endif - if (err) - goto out3; - - printk( KERN_INFO "Probing ACSI devices:\n" ); - NDevices = 0; -#ifdef CONFIG_ATARI_SLM_MODULE - for( i = 0; i < 8; ++i ) - SLM_devices[i] = -1; -#endif - stdma_lock(NULL, NULL); - - for (target = 0; target < 8 && NDevices < MAX_DEV; ++target) { - lun = 0; - do { - aip = &acsi_info[NDevices]; - aip->type = NONE; - aip->target = target; - aip->lun = lun; - i = acsi_devinit(aip); - switch (i) { - case DEV_SUPPORTED: - printk( KERN_INFO "Detected "); - switch (aip->type) { - case HARDDISK: - printk("disk"); - break; - case CDROM: - printk("cdrom"); - break; - default: - } - printk(" ad%c at id %d lun %d ", - 'a' + NDevices, target, lun); - if (aip->removable) - printk("(removable) "); - if (aip->read_only) - printk("(read-only) "); - if (aip->size == DEFAULT_SIZE) - printk(" unkown size, using default "); - printk("%ld MByte\n", - (aip->size*512+1024*1024/2)/(1024*1024)); - NDevices++; - break; - case DEV_SLM: -#ifdef CONFIG_ATARI_SLM - n_slm += attach_slm( target, lun ); - break; -#endif -#ifdef CONFIG_ATARI_SLM_MODULE - SLM_devices[target] = lun; - break; -#endif - /* neither of the above: fall through to unknown device */ - case DEV_UNKNOWN: - printk( KERN_INFO "Detected unsupported device at " - "id %d lun %d\n", target, lun); - break; - } - } -#ifdef CONFIG_ACSI_MULTI_LUN - while (i != DEV_NONE && ++lun < MAX_LUN); -#else - while (0); -#endif - } - - /* reenable interrupt */ - ENABLE_IRQ(); - stdma_release(); - -#ifndef CONFIG_ATARI_SLM - printk( KERN_INFO "Found %d ACSI device(s) total.\n", NDevices ); -#else - printk( KERN_INFO "Found %d ACSI device(s) and %d SLM printer(s) total.\n", - NDevices, n_slm ); -#endif - err = -ENOMEM; - for( i = 0; i < NDevices; ++i ) { - acsi_gendisk[i] = alloc_disk(16); - if (!acsi_gendisk[i]) - goto out4; - } - - for( i = 0; i < NDevices; ++i ) { - struct gendisk *disk = acsi_gendisk[i]; - sprintf(disk->disk_name, "ad%c", 'a'+i); - aip = &acsi_info[NDevices]; - disk->major = ACSI_MAJOR; - disk->first_minor = i << 4; - if (acsi_info[i].type != HARDDISK) - disk->minors = 1; - disk->fops = &acsi_fops; - disk->private_data = &acsi_info[i]; - set_capacity(disk, acsi_info[i].size); - disk->queue = acsi_queue; - add_disk(disk); - } - return 0; -out4: - while (i--) - put_disk(acsi_gendisk[i]); -out3: - blk_cleanup_queue(acsi_queue); -out2a: - atari_stram_free( acsi_buffer ); -out2: - unregister_blkdev( ACSI_MAJOR, "ad" ); -out1: - return err; -} - - -#ifdef MODULE - -MODULE_LICENSE("GPL"); - -int init_module(void) -{ - int err; - - if ((err = acsi_init())) - return( err ); - printk( KERN_INFO "ACSI driver loaded as module.\n"); - return( 0 ); -} - -void cleanup_module(void) -{ - int i; - del_timer( &acsi_timer ); - blk_cleanup_queue(acsi_queue); - atari_stram_free( acsi_buffer ); - - if (unregister_blkdev( ACSI_MAJOR, "ad" ) != 0) - printk( KERN_ERR "acsi: cleanup_module failed\n"); - - for (i = 0; i < NDevices; i++) { - del_gendisk(acsi_gendisk[i]); - put_disk(acsi_gendisk[i]); - } -} -#endif - -/* - * This routine is called to flush all partitions and partition tables - * for a changed scsi disk, and then re-read the new partition table. - * If we are revalidating a disk because of a media change, then we - * enter with usage == 0. If we are using an ioctl, we automatically have - * usage == 1 (we need an open channel to use an ioctl :-), so this - * is our limit. - * - * Changes by Martin Rogge, 9th Aug 1995: - * got cd-roms to work by calling acsi_devinit. There are only two problems: - * First, if there is no medium inserted, the status will remain "changed". - * That is no problem at all, but our design of three-valued logic (medium - * changed, medium not changed, no medium inserted). - * Secondly the check could fail completely and the drive could deliver - * nonsensical data, which could mess up the acsi_info[] structure. In - * that case we try to make the entry safe. - * - */ - -static int acsi_revalidate(struct gendisk *disk) -{ - struct acsi_info_struct *aip = disk->private_data; - stdma_lock( NULL, NULL ); - if (acsi_devinit(aip) != DEV_SUPPORTED) { - printk( KERN_ERR "ACSI: revalidate failed for target %d lun %d\n", - aip->target, aip->lun); - aip->size = 0; - aip->read_only = 1; - aip->removable = 1; - aip->changed = 1; /* next acsi_open will try again... */ - } - - ENABLE_IRQ(); - stdma_release(); - set_capacity(disk, aip->size); - return 0; -} diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c deleted file mode 100644 index 1d9d9b4f48cc..000000000000 --- a/drivers/block/acsi_slm.c +++ /dev/null @@ -1,1032 +0,0 @@ -/* - * acsi_slm.c -- Device driver for the Atari SLM laser printer - * - * Copyright 1995 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - * - */ - -/* - -Notes: - -The major number for SLM printers is 28 (like ACSI), but as a character -device, not block device. The minor number is the number of the printer (if -you have more than one SLM; currently max. 2 (#define-constant) SLMs are -supported). The device can be opened for reading and writing. If reading it, -you get some status infos (MODE SENSE data). Writing mode is used for the data -to be printed. Some ioctls allow to get the printer status and to tune printer -modes and some internal variables. - -A special problem of the SLM driver is the timing and thus the buffering of -the print data. The problem is that all the data for one page must be present -in memory when printing starts, else --when swapping occurs-- the timing could -not be guaranteed. There are several ways to assure this: - - 1) Reserve a buffer of 1196k (maximum page size) statically by - atari_stram_alloc(). The data are collected there until they're complete, - and then printing starts. Since the buffer is reserved, no further - considerations about memory and swapping are needed. So this is the - simplest method, but it needs a lot of memory for just the SLM. - - An striking advantage of this method is (supposed the SLM_CONT_CNT_REPROG - method works, see there), that there are no timing problems with the DMA - anymore. - - 2) The other method would be to reserve the buffer dynamically each time - printing is required. I could think of looking at mem_map where the - largest unallocted ST-RAM area is, taking the area, and then extending it - by swapping out the neighbored pages, until the needed size is reached. - This requires some mm hacking, but seems possible. The only obstacle could - be pages that cannot be swapped out (reserved pages)... - - 3) Another possibility would be to leave the real data in user space and to - work with two dribble buffers of about 32k in the driver: While the one - buffer is DMAed to the SLM, the other can be filled with new data. But - to keep the timing, that requires that the user data remain in memory and - are not swapped out. Requires mm hacking, too, but maybe not so bad as - method 2). - -*/ - -#include <linux/module.h> - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/fs.h> -#include <linux/major.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/time.h> -#include <linux/mm.h> -#include <linux/slab.h> - -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/uaccess.h> -#include <asm/atarihw.h> -#include <asm/atariints.h> -#include <asm/atari_acsi.h> -#include <asm/atari_stdma.h> -#include <asm/atari_stram.h> -#include <asm/atari_SLM.h> - - -#undef DEBUG - -/* Define this if the page data are continuous in physical memory. That - * requires less reprogramming of the ST-DMA */ -#define SLM_CONTINUOUS_DMA - -/* Use continuous reprogramming of the ST-DMA counter register. This is - * --strictly speaking-- not allowed, Atari recommends not to look at the - * counter register while a DMA is going on. But I don't know if that applies - * only for reading the register, or also writing to it. Writing only works - * fine for me... The advantage is that the timing becomes absolutely - * uncritical: Just update each, say 200ms, the counter reg to its maximum, - * and the DMA will work until the status byte interrupt occurs. - */ -#define SLM_CONT_CNT_REPROG - -#define CMDSET_TARG_LUN(cmd,targ,lun) \ - do { \ - cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5; \ - cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5; \ - } while(0) - -#define START_TIMER(to) mod_timer(&slm_timer, jiffies + (to)) -#define STOP_TIMER() del_timer(&slm_timer) - - -static char slmreqsense_cmd[6] = { 0x03, 0, 0, 0, 0, 0 }; -static char slmprint_cmd[6] = { 0x0a, 0, 0, 0, 0, 0 }; -static char slminquiry_cmd[6] = { 0x12, 0, 0, 0, 0, 0x80 }; -static char slmmsense_cmd[6] = { 0x1a, 0, 0, 0, 255, 0 }; -#if 0 -static char slmmselect_cmd[6] = { 0x15, 0, 0, 0, 0, 0 }; -#endif - - -#define MAX_SLM 2 - -static struct slm { - unsigned target; /* target number */ - unsigned lun; /* LUN in target controller */ - atomic_t wr_ok; /* set to 0 if output part busy */ - atomic_t rd_ok; /* set to 0 if status part busy */ -} slm_info[MAX_SLM]; - -int N_SLM_Printers = 0; - -/* printer buffer */ -static unsigned char *SLMBuffer; /* start of buffer */ -static unsigned char *BufferP; /* current position in buffer */ -static int BufferSize; /* length of buffer for page size */ - -typedef enum { IDLE, FILLING, PRINTING } SLMSTATE; -static SLMSTATE SLMState; -static int SLMBufOwner; /* SLM# currently using the buffer */ - -/* DMA variables */ -#ifndef SLM_CONT_CNT_REPROG -static unsigned long SLMCurAddr; /* current base addr of DMA chunk */ -static unsigned long SLMEndAddr; /* expected end addr */ -static unsigned long SLMSliceSize; /* size of one DMA chunk */ -#endif -static int SLMError; - -/* wait queues */ -static DECLARE_WAIT_QUEUE_HEAD(slm_wait); /* waiting for buffer */ -static DECLARE_WAIT_QUEUE_HEAD(print_wait); /* waiting for printing finished */ - -/* status codes */ -#define SLMSTAT_OK 0x00 -#define SLMSTAT_ORNERY 0x02 -#define SLMSTAT_TONER 0x03 -#define SLMSTAT_WARMUP 0x04 -#define SLMSTAT_PAPER 0x05 -#define SLMSTAT_DRUM 0x06 -#define SLMSTAT_INJAM 0x07 -#define SLMSTAT_THRJAM 0x08 -#define SLMSTAT_OUTJAM 0x09 -#define SLMSTAT_COVER 0x0a -#define SLMSTAT_FUSER 0x0b -#define SLMSTAT_IMAGER 0x0c -#define SLMSTAT_MOTOR 0x0d -#define SLMSTAT_VIDEO 0x0e -#define SLMSTAT_SYSTO 0x10 -#define SLMSTAT_OPCODE 0x12 -#define SLMSTAT_DEVNUM 0x15 -#define SLMSTAT_PARAM 0x1a -#define SLMSTAT_ACSITO 0x1b /* driver defined */ -#define SLMSTAT_NOTALL 0x1c /* driver defined */ - -static char *SLMErrors[] = { - /* 0x00 */ "OK and ready", - /* 0x01 */ NULL, - /* 0x02 */ "ornery printer", - /* 0x03 */ "toner empty", - /* 0x04 */ "warming up", - /* 0x05 */ "paper empty", - /* 0x06 */ "drum empty", - /* 0x07 */ "input jam", - /* 0x08 */ "through jam", - /* 0x09 */ "output jam", - /* 0x0a */ "cover open", - /* 0x0b */ "fuser malfunction", - /* 0x0c */ "imager malfunction", - /* 0x0d */ "motor malfunction", - /* 0x0e */ "video malfunction", - /* 0x0f */ NULL, - /* 0x10 */ "printer system timeout", - /* 0x11 */ NULL, - /* 0x12 */ "invalid operation code", - /* 0x13 */ NULL, - /* 0x14 */ NULL, - /* 0x15 */ "invalid device number", - /* 0x16 */ NULL, - /* 0x17 */ NULL, - /* 0x18 */ NULL, - /* 0x19 */ NULL, - /* 0x1a */ "invalid parameter list", - /* 0x1b */ "ACSI timeout", - /* 0x1c */ "not all printed" -}; - -#define N_ERRORS (sizeof(SLMErrors)/sizeof(*SLMErrors)) - -/* real (driver caused) error? */ -#define IS_REAL_ERROR(x) (x > 0x10) - - -static struct { - char *name; - int w, h; -} StdPageSize[] = { - { "Letter", 2400, 3180 }, - { "Legal", 2400, 4080 }, - { "A4", 2336, 3386 }, - { "B5", 2016, 2914 } -}; - -#define N_STD_SIZES (sizeof(StdPageSize)/sizeof(*StdPageSize)) - -#define SLM_BUFFER_SIZE (2336*3386/8) /* A4 for now */ -#define SLM_DMA_AMOUNT 255 /* #sectors to program the DMA for */ - -#ifdef SLM_CONTINUOUS_DMA -# define SLM_DMA_INT_OFFSET 0 /* DMA goes until seccnt 0, no offs */ -# define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */ -# define SLM_SLICE_SIZE(w) (255*512) -#else -# define SLM_DMA_INT_OFFSET 32 /* 32 Byte ST-DMA FIFO */ -# define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */ -# define SLM_SLICE_SIZE(w) ((254*512)/(w/8)*(w/8)) -#endif - -/* calculate the number of jiffies to wait for 'n' bytes */ -#ifdef SLM_CONT_CNT_REPROG -#define DMA_TIME_FOR(n) 50 -#define DMA_STARTUP_TIME 0 -#else -#define DMA_TIME_FOR(n) (n/1400-1) -#define DMA_STARTUP_TIME 650 -#endif - -/***************************** Prototypes *****************************/ - -static char *slm_errstr( int stat ); -static int slm_getstats( char *buffer, int device ); -static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t - *ppos ); -static void start_print( int device ); -static irqreturn_t slm_interrupt(int irc, void *data); -static void slm_test_ready( unsigned long dummy ); -static void set_dma_addr( unsigned long paddr ); -static unsigned long get_dma_addr( void ); -static ssize_t slm_write( struct file *file, const char *buf, size_t count, - loff_t *ppos ); -static int slm_ioctl( struct inode *inode, struct file *file, unsigned int - cmd, unsigned long arg ); -static int slm_open( struct inode *inode, struct file *file ); -static int slm_release( struct inode *inode, struct file *file ); -static int slm_req_sense( int device ); -static int slm_mode_sense( int device, char *buffer, int abs_flag ); -#if 0 -static int slm_mode_select( int device, char *buffer, int len, int - default_flag ); -#endif -static int slm_get_pagesize( int device, int *w, int *h ); - -/************************* End of Prototypes **************************/ - - -static DEFINE_TIMER(slm_timer, slm_test_ready, 0, 0); - -static const struct file_operations slm_fops = { - .owner = THIS_MODULE, - .read = slm_read, - .write = slm_write, - .ioctl = slm_ioctl, - .open = slm_open, - .release = slm_release, -}; - - -/* ---------------------------------------------------------------------- */ -/* Status Functions */ - - -static char *slm_errstr( int stat ) - -{ char *p; - static char str[22]; - - stat &= 0x1f; - if (stat >= 0 && stat < N_ERRORS && (p = SLMErrors[stat])) - return( p ); - sprintf( str, "unknown status 0x%02x", stat ); - return( str ); -} - - -static int slm_getstats( char *buffer, int device ) - -{ int len = 0, stat, i, w, h; - unsigned char buf[256]; - - stat = slm_mode_sense( device, buf, 0 ); - if (IS_REAL_ERROR(stat)) - return( -EIO ); - -#define SHORTDATA(i) ((buf[i] << 8) | buf[i+1]) -#define BOOLDATA(i,mask) ((buf[i] & mask) ? "on" : "off") - - w = SHORTDATA( 3 ); - h = SHORTDATA( 1 ); - - len += sprintf( buffer+len, "Status\t\t%s\n", - slm_errstr( stat ) ); - len += sprintf( buffer+len, "Page Size\t%dx%d", - w, h ); - - for( i = 0; i < N_STD_SIZES; ++i ) { - if (w == StdPageSize[i].w && h == StdPageSize[i].h) - break; - } - if (i < N_STD_SIZES) - len += sprintf( buffer+len, " (%s)", StdPageSize[i].name ); - buffer[len++] = '\n'; - - len += sprintf( buffer+len, "Top/Left Margin\t%d/%d\n", - SHORTDATA( 5 ), SHORTDATA( 7 ) ); - len += sprintf( buffer+len, "Manual Feed\t%s\n", - BOOLDATA( 9, 0x01 ) ); - len += sprintf( buffer+len, "Input Select\t%d\n", - (buf[9] >> 1) & 7 ); - len += sprintf( buffer+len, "Auto Select\t%s\n", - BOOLDATA( 9, 0x10 ) ); - len += sprintf( buffer+len, "Prefeed Paper\t%s\n", - BOOLDATA( 9, 0x20 ) ); - len += sprintf( buffer+len, "Thick Pixels\t%s\n", - BOOLDATA( 9, 0x40 ) ); - len += sprintf( buffer+len, "H/V Resol.\t%d/%d dpi\n", - SHORTDATA( 12 ), SHORTDATA( 10 ) ); - len += sprintf( buffer+len, "System Timeout\t%d\n", - buf[14] ); - len += sprintf( buffer+len, "Scan Time\t%d\n", - SHORTDATA( 15 ) ); - len += sprintf( buffer+len, "Page Count\t%d\n", - SHORTDATA( 17 ) ); - len += sprintf( buffer+len, "In/Out Cap.\t%d/%d\n", - SHORTDATA( 19 ), SHORTDATA( 21 ) ); - len += sprintf( buffer+len, "Stagger Output\t%s\n", - BOOLDATA( 23, 0x01 ) ); - len += sprintf( buffer+len, "Output Select\t%d\n", - (buf[23] >> 1) & 7 ); - len += sprintf( buffer+len, "Duplex Print\t%s\n", - BOOLDATA( 23, 0x10 ) ); - len += sprintf( buffer+len, "Color Sep.\t%s\n", - BOOLDATA( 23, 0x20 ) ); - - return( len ); -} - - -static ssize_t slm_read( struct file *file, char *buf, size_t count, - loff_t *ppos ) - -{ - struct inode *node = file->f_path.dentry->d_inode; - unsigned long page; - int length; - int end; - - if (!(page = __get_free_page( GFP_KERNEL ))) - return( -ENOMEM ); - - length = slm_getstats( (char *)page, iminor(node) ); - if (length < 0) { - count = length; - goto out; - } - if (file->f_pos >= length) { - count = 0; - goto out; - } - if (count + file->f_pos > length) - count = length - file->f_pos; - end = count + file->f_pos; - if (copy_to_user(buf, (char *)page + file->f_pos, count)) { - count = -EFAULT; - goto out; - } - file->f_pos = end; -out: free_page( page ); - return( count ); -} - - -/* ---------------------------------------------------------------------- */ -/* Printing */ - - -static void start_print( int device ) - -{ struct slm *sip = &slm_info[device]; - unsigned char *cmd; - unsigned long paddr; - int i; - - stdma_lock( slm_interrupt, NULL ); - - CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun ); - cmd = slmprint_cmd; - paddr = virt_to_phys( SLMBuffer ); - dma_cache_maintenance( paddr, virt_to_phys(BufferP)-paddr, 1 ); - DISABLE_IRQ(); - - /* Low on A1 */ - dma_wd.dma_mode_status = 0x88; - MFPDELAY(); - - /* send the command bytes except the last */ - for( i = 0; i < 5; ++i ) { - DMA_LONG_WRITE( *cmd++, 0x8a ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) { - SLMError = 1; - return; /* timeout */ - } - } - /* last command byte */ - DMA_LONG_WRITE( *cmd++, 0x82 ); - MFPDELAY(); - /* set DMA address */ - set_dma_addr( paddr ); - /* program DMA for write and select sector counter reg */ - dma_wd.dma_mode_status = 0x192; - MFPDELAY(); - /* program for 255*512 bytes and start DMA */ - DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 ); - -#ifndef SLM_CONT_CNT_REPROG - SLMCurAddr = paddr; - SLMEndAddr = paddr + SLMSliceSize + SLM_DMA_INT_OFFSET; -#endif - START_TIMER( DMA_STARTUP_TIME + DMA_TIME_FOR( SLMSliceSize )); -#if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG) - printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n", - SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) ); -#endif - - ENABLE_IRQ(); -} - - -/* Only called when an error happened or at the end of a page */ - -static irqreturn_t slm_interrupt(int irc, void *data) - -{ unsigned long addr; - int stat; - - STOP_TIMER(); - addr = get_dma_addr(); - stat = acsi_getstatus(); - SLMError = (stat < 0) ? SLMSTAT_ACSITO : - (addr < virt_to_phys(BufferP)) ? SLMSTAT_NOTALL : - stat; - - dma_wd.dma_mode_status = 0x80; - MFPDELAY(); -#ifdef DEBUG - printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr, SLMError ); -#endif - - wake_up( &print_wait ); - stdma_release(); - ENABLE_IRQ(); - return IRQ_HANDLED; -} - - -static void slm_test_ready( unsigned long dummy ) - -{ -#ifdef SLM_CONT_CNT_REPROG - /* program for 255*512 bytes again */ - dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT; - START_TIMER( DMA_TIME_FOR(0) ); -#ifdef DEBUG - printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n", - DMA_TIME_FOR(0), get_dma_addr() ); -#endif - -#else /* !SLM_CONT_CNT_REPROG */ - - unsigned long flags, addr; - int d, ti; -#ifdef DEBUG - struct timeval start_tm, end_tm; - int did_wait = 0; -#endif - - local_irq_save(flags); - - addr = get_dma_addr(); - if ((d = SLMEndAddr - addr) > 0) { - local_irq_restore(flags); - - /* slice not yet finished, decide whether to start another timer or to - * busy-wait */ - ti = DMA_TIME_FOR( d ); - if (ti > 0) { -#ifdef DEBUG - printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n", - ti, d ); -#endif - START_TIMER( ti ); - return; - } - /* wait for desired end address to be reached */ -#ifdef DEBUG - do_gettimeofday( &start_tm ); - did_wait = 1; -#endif - local_irq_disable(); - while( get_dma_addr() < SLMEndAddr ) - barrier(); - } - - /* slice finished, start next one */ - SLMCurAddr += SLMSliceSize; - -#ifdef SLM_CONTINUOUS_DMA - /* program for 255*512 bytes again */ - dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT; -#else - /* set DMA address; - * add 2 bytes for the ones in the SLM controller FIFO! */ - set_dma_addr( SLMCurAddr + 2 ); - /* toggle DMA to write and select sector counter reg */ - dma_wd.dma_mode_status = 0x92; - MFPDELAY(); - dma_wd.dma_mode_status = 0x192; - MFPDELAY(); - /* program for 255*512 bytes and start DMA */ - DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 ); -#endif - - local_irq_restore(flags); - -#ifdef DEBUG - if (did_wait) { - int ms; - do_gettimeofday( &end_tm ); - ms = (end_tm.tv_sec*1000000+end_tm.tv_usec) - - (start_tm.tv_sec*1000000+start_tm.tv_usec); - printk( "SLM: did %ld.%ld ms busy waiting for %d bytes\n", - ms/1000, ms%1000, d ); - } - else - printk( "SLM: didn't wait (!)\n" ); -#endif - - if ((unsigned char *)PTOV( SLMCurAddr + SLMSliceSize ) >= BufferP) { - /* will be last slice, no timer necessary */ -#ifdef DEBUG - printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n", - SLMCurAddr, SLMEndAddr ); -#endif - } - else { - /* not last slice */ - SLMEndAddr = SLMCurAddr + SLMSliceSize + SLM_DMA_INT_OFFSET; - START_TIMER( DMA_TIME_FOR( SLMSliceSize )); -#ifdef DEBUG - printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n", - SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) ); -#endif - } -#endif /* SLM_CONT_CNT_REPROG */ -} - - -static void set_dma_addr( unsigned long paddr ) - -{ unsigned long flags; - - local_irq_save(flags); - dma_wd.dma_lo = (unsigned char)paddr; - paddr >>= 8; - MFPDELAY(); - dma_wd.dma_md = (unsigned char)paddr; - paddr >>= 8; - MFPDELAY(); - if (ATARIHW_PRESENT( EXTD_DMA )) - st_dma_ext_dmahi = (unsigned short)paddr; - else - dma_wd.dma_hi = (unsigned char)paddr; - MFPDELAY(); - local_irq_restore(flags); -} - - -static unsigned long get_dma_addr( void ) - -{ unsigned long addr; - - addr = dma_wd.dma_lo & 0xff; - MFPDELAY(); - addr |= (dma_wd.dma_md & 0xff) << 8; - MFPDELAY(); - addr |= (dma_wd.dma_hi & 0xff) << 16; - MFPDELAY(); - - return( addr ); -} - - -static ssize_t slm_write( struct file *file, const char *buf, size_t count, - loff_t *ppos ) - -{ - struct inode *node = file->f_path.dentry->d_inode; - int device = iminor(node); - int n, filled, w, h; - - while( SLMState == PRINTING || - (SLMState == FILLING && SLMBufOwner != device) ) { - interruptible_sleep_on( &slm_wait ); - if (signal_pending(current)) - return( -ERESTARTSYS ); - } - if (SLMState == IDLE) { - /* first data of page: get current page size */ - if (slm_get_pagesize( device, &w, &h )) - return( -EIO ); - BufferSize = w*h/8; - if (BufferSize > SLM_BUFFER_SIZE) - return( -ENOMEM ); - - SLMState = FILLING; - SLMBufOwner = device; - } - - n = count; - filled = BufferP - SLMBuffer; - if (filled + n > BufferSize) - n = BufferSize - filled; - - if (copy_from_user(BufferP, buf, n)) - return -EFAULT; - BufferP += n; - filled += n; - - if (filled == BufferSize) { - /* Check the paper size again! The user may have switched it in the - * time between starting the data and finishing them. Would end up in - * a trashy page... */ - if (slm_get_pagesize( device, &w, &h )) - return( -EIO ); - if (BufferSize != w*h/8) { - printk( KERN_NOTICE "slm%d: page size changed while printing\n", - device ); - return( -EAGAIN ); - } - - SLMState = PRINTING; - /* choose a slice size that is a multiple of the line size */ -#ifndef SLM_CONT_CNT_REPROG - SLMSliceSize = SLM_SLICE_SIZE(w); -#endif - - start_print( device ); - sleep_on( &print_wait ); - if (SLMError && IS_REAL_ERROR(SLMError)) { - printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) ); - n = -EIO; - } - - SLMState = IDLE; - BufferP = SLMBuffer; - wake_up_interruptible( &slm_wait ); - } - - return( n ); -} - - -/* ---------------------------------------------------------------------- */ -/* ioctl Functions */ - - -static int slm_ioctl( struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg ) - -{ int device = iminor(inode), err; - - /* I can think of setting: - * - manual feed - * - paper format - * - copy count - * - ... - * but haven't implemented that yet :-) - * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data? - */ - switch( cmd ) { - - case SLMIORESET: /* reset buffer, i.e. empty the buffer */ - if (!(file->f_mode & 2)) - return( -EINVAL ); - if (SLMState == PRINTING) - return( -EBUSY ); - SLMState = IDLE; - BufferP = SLMBuffer; - wake_up_interruptible( &slm_wait ); - return( 0 ); - - case SLMIOGSTAT: { /* get status */ - int stat; - char *str; - - stat = slm_req_sense( device ); - if (arg) { - str = slm_errstr( stat ); - if (put_user(stat, - (long *)&((struct SLM_status *)arg)->stat)) - return -EFAULT; - if (copy_to_user( ((struct SLM_status *)arg)->str, str, - strlen(str) + 1)) - return -EFAULT; - } - return( stat ); - } - - case SLMIOGPSIZE: { /* get paper size */ - int w, h; - - if ((err = slm_get_pagesize( device, &w, &h ))) return( err ); - - if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width)) - return -EFAULT; - if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height)) - return -EFAULT; - return( 0 ); - } - - case SLMIOGMFEED: /* get manual feed */ - return( -EINVAL ); - - case SLMIOSPSIZE: /* set paper size */ - return( -EINVAL ); - - case SLMIOSMFEED: /* set manual feed */ - return( -EINVAL ); - - } - return( -EINVAL ); -} - - -/* ---------------------------------------------------------------------- */ -/* Opening and Closing */ - - -static int slm_open( struct inode *inode, struct file *file ) - -{ int device; - struct slm *sip; - - device = iminor(inode); - if (device >= N_SLM_Printers) - return( -ENXIO ); - sip = &slm_info[device]; - - if (file->f_mode & 2) { - /* open for writing is exclusive */ - if ( !atomic_dec_and_test(&sip->wr_ok) ) { - atomic_inc(&sip->wr_ok); - return( -EBUSY ); - } - } - if (file->f_mode & 1) { - /* open for reading is exclusive */ - if ( !atomic_dec_and_test(&sip->rd_ok) ) { - atomic_inc(&sip->rd_ok); - return( -EBUSY ); - } - } - - return( 0 ); -} - - -static int slm_release( struct inode *inode, struct file *file ) - -{ int device; - struct slm *sip; - - device = iminor(inode); - sip = &slm_info[device]; - - if (file->f_mode & 2) - atomic_inc( &sip->wr_ok ); - if (file->f_mode & 1) - atomic_inc( &sip->rd_ok ); - - return( 0 ); -} - - -/* ---------------------------------------------------------------------- */ -/* ACSI Primitives for the SLM */ - - -static int slm_req_sense( int device ) - -{ int stat, rv; - struct slm *sip = &slm_info[device]; - - stdma_lock( NULL, NULL ); - - CMDSET_TARG_LUN( slmreqsense_cmd, sip->target, sip->lun ); - if (!acsicmd_nodma( slmreqsense_cmd, 0 ) || - (stat = acsi_getstatus()) < 0) - rv = SLMSTAT_ACSITO; - else - rv = stat & 0x1f; - - ENABLE_IRQ(); - stdma_release(); - return( rv ); -} - - -static int slm_mode_sense( int device, char *buffer, int abs_flag ) - -{ unsigned char stat, len; - int rv = 0; - struct slm *sip = &slm_info[device]; - - stdma_lock( NULL, NULL ); - - CMDSET_TARG_LUN( slmmsense_cmd, sip->target, sip->lun ); - slmmsense_cmd[5] = abs_flag ? 0x80 : 0; - if (!acsicmd_nodma( slmmsense_cmd, 0 )) { - rv = SLMSTAT_ACSITO; - goto the_end; - } - - if (!acsi_extstatus( &stat, 1 )) { - acsi_end_extstatus(); - rv = SLMSTAT_ACSITO; - goto the_end; - } - - if (!acsi_extstatus( &len, 1 )) { - acsi_end_extstatus(); - rv = SLMSTAT_ACSITO; - goto the_end; - } - buffer[0] = len; - if (!acsi_extstatus( buffer+1, len )) { - acsi_end_extstatus(); - rv = SLMSTAT_ACSITO; - goto the_end; - } - - acsi_end_extstatus(); - rv = stat & 0x1f; - - the_end: - ENABLE_IRQ(); - stdma_release(); - return( rv ); -} - - -#if 0 -/* currently unused */ -static int slm_mode_select( int device, char *buffer, int len, - int default_flag ) - -{ int stat, rv; - struct slm *sip = &slm_info[device]; - - stdma_lock( NULL, NULL ); - - CMDSET_TARG_LUN( slmmselect_cmd, sip->target, sip->lun ); - slmmselect_cmd[5] = default_flag ? 0x80 : 0; - if (!acsicmd_nodma( slmmselect_cmd, 0 )) { - rv = SLMSTAT_ACSITO; - goto the_end; - } - - if (!default_flag) { - unsigned char c = len; - if (!acsi_extcmd( &c, 1 )) { - rv = SLMSTAT_ACSITO; - goto the_end; - } - if (!acsi_extcmd( buffer, len )) { - rv = SLMSTAT_ACSITO; - goto the_end; - } - } - - stat = acsi_getstatus(); - rv = (stat < 0 ? SLMSTAT_ACSITO : stat); - - the_end: - ENABLE_IRQ(); - stdma_release(); - return( rv ); -} -#endif - - -static int slm_get_pagesize( int device, int *w, int *h ) - -{ char buf[256]; - int stat; - - stat = slm_mode_sense( device, buf, 0 ); - ENABLE_IRQ(); - stdma_release(); - - if (stat != SLMSTAT_OK) - return( -EIO ); - - *w = (buf[3] << 8) | buf[4]; - *h = (buf[1] << 8) | buf[2]; - return( 0 ); -} - - -/* ---------------------------------------------------------------------- */ -/* Initialization */ - - -int attach_slm( int target, int lun ) - -{ static int did_register; - int len; - - if (N_SLM_Printers >= MAX_SLM) { - printk( KERN_WARNING "Too much SLMs\n" ); - return( 0 ); - } - - /* do an INQUIRY */ - udelay(100); - CMDSET_TARG_LUN( slminquiry_cmd, target, lun ); - if (!acsicmd_nodma( slminquiry_cmd, 0 )) { - inq_timeout: - printk( KERN_ERR "SLM inquiry command timed out.\n" ); - inq_fail: - acsi_end_extstatus(); - return( 0 ); - } - /* read status and header of return data */ - if (!acsi_extstatus( SLMBuffer, 6 )) - goto inq_timeout; - - if (SLMBuffer[1] != 2) { /* device type == printer? */ - printk( KERN_ERR "SLM inquiry returned device type != printer\n" ); - goto inq_fail; - } - len = SLMBuffer[5]; - - /* read id string */ - if (!acsi_extstatus( SLMBuffer, len )) - goto inq_timeout; - acsi_end_extstatus(); - SLMBuffer[len] = 0; - - if (!did_register) { - did_register = 1; - } - - slm_info[N_SLM_Printers].target = target; - slm_info[N_SLM_Printers].lun = lun; - atomic_set(&slm_info[N_SLM_Printers].wr_ok, 1 ); - atomic_set(&slm_info[N_SLM_Printers].rd_ok, 1 ); - - printk( KERN_INFO " Printer: %s\n", SLMBuffer ); - printk( KERN_INFO "Detected slm%d at id %d lun %d\n", - N_SLM_Printers, target, lun ); - N_SLM_Printers++; - return( 1 ); -} - -int slm_init( void ) - -{ - int i; - if (register_chrdev( ACSI_MAJOR, "slm", &slm_fops )) { - printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", ACSI_MAJOR ); - return -EBUSY; - } - - if (!(SLMBuffer = atari_stram_alloc( SLM_BUFFER_SIZE, "SLM" ))) { - printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" ); - unregister_chrdev( ACSI_MAJOR, "slm" ); - return -ENOMEM; - } - BufferP = SLMBuffer; - SLMState = IDLE; - - return 0; -} - -#ifdef MODULE - -/* from acsi.c */ -void acsi_attach_SLMs( int (*attach_func)( int, int ) ); - -int init_module(void) -{ - int err; - - if ((err = slm_init())) - return( err ); - /* This calls attach_slm() for every target/lun where acsi.c detected a - * printer */ - acsi_attach_SLMs( attach_slm ); - return( 0 ); -} - -void cleanup_module(void) -{ - if (unregister_chrdev( ACSI_MAJOR, "slm" ) != 0) - printk( KERN_ERR "acsi_slm: cleanup_module failed\n"); - atari_stram_free( SLMBuffer ); -} -#endif diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 27a139025ced..c9751b2b57e6 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1363,7 +1363,7 @@ static void redo_fd_request(void) #ifdef DEBUG printk("fd: sector %ld + %d requested for %s\n", CURRENT->sector,cnt, - (CURRENT->cmd==READ)?"read":"write"); + (rq_data_dir(CURRENT) == READ) ? "read" : "write"); #endif block = CURRENT->sector + cnt; if ((int)block > floppy->blocks) { @@ -1422,7 +1422,7 @@ static void redo_fd_request(void) goto repeat; } -static void do_fd_request(request_queue_t * q) +static void do_fd_request(struct request_queue * q) { redo_fd_request(); } diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 1d8466817943..ba07f762c4cb 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -138,7 +138,7 @@ struct aoedev { u16 maxbcnt; struct work_struct work;/* disk create work struct */ struct gendisk *gd; - request_queue_t blkq; + struct request_queue blkq; struct hd_geometry geo; sector_t ssize; struct timer_list timer; diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 478489c568a4..007faaf008e7 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -125,7 +125,7 @@ aoeblk_release(struct inode *inode, struct file *filp) } static int -aoeblk_make_request(request_queue_t *q, struct bio *bio) +aoeblk_make_request(struct request_queue *q, struct bio *bio) { struct aoedev *d; struct buf *buf; @@ -257,9 +257,9 @@ aoeblk_exit(void) int __init aoeblk_init(void) { - buf_pool_cache = kmem_cache_create("aoe_bufs", + buf_pool_cache = kmem_cache_create("aoe_bufs", sizeof(struct buf), - 0, 0, NULL, NULL); + 0, 0, NULL); if (buf_pool_cache == NULL) return -ENOMEM; diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 14d6b9492750..94268c75d04f 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -1466,7 +1466,7 @@ repeat: } -void do_fd_request(request_queue_t * q) +void do_fd_request(struct request_queue * q) { unsigned long flags; diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 5acc6c44aead..084358a828e9 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -87,6 +87,7 @@ static const struct pci_device_id cciss_pci_device_id[] = { {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3214}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D}, {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, {0,} @@ -119,6 +120,7 @@ static struct board_type products[] = { {0x3214103C, "Smart Array E200i", &SA5_access, 120}, {0x3215103C, "Smart Array E200i", &SA5_access, 120}, {0x3237103C, "Smart Array E500", &SA5_access, 512}, + {0x323D103C, "Smart Array P700m", &SA5_access, 512}, {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, }; @@ -137,7 +139,7 @@ static struct board_type products[] = { static ctlr_info_t *hba[MAX_CTLR]; -static void do_cciss_request(request_queue_t *q); +static void do_cciss_request(struct request_queue *q); static irqreturn_t do_cciss_intr(int irq, void *dev_id); static int cciss_open(struct inode *inode, struct file *filep); static int cciss_release(struct inode *inode, struct file *filep); @@ -1168,7 +1170,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, case SG_EMULATED_HOST: case SG_IO: case SCSI_IOCTL_SEND_COMMAND: - return scsi_cmd_ioctl(filep, disk, cmd, argp); + return scsi_cmd_ioctl(filep, disk->queue, disk, cmd, argp); /* scsi_cmd_ioctl would normally handle these, below, but */ /* they aren't a good fit for cciss, as CD-ROMs are */ @@ -1582,7 +1584,7 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, */ if (h->gendisk[0] != disk) { if (disk) { - request_queue_t *q = disk->queue; + struct request_queue *q = disk->queue; if (disk->flags & GENHD_FL_UP) del_gendisk(disk); if (q) { @@ -1975,12 +1977,13 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, { ReadCapdata_struct *buf; int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); - if (buf == NULL) { + + buf = kzalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); + if (!buf) { printk(KERN_WARNING "cciss: out of memory\n"); return; } - memset(buf, 0, sizeof(ReadCapdata_struct)); + if (withirq) return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, buf, sizeof(ReadCapdata_struct), @@ -2001,7 +2004,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, printk(KERN_INFO " blocks= %llu block_size= %d\n", (unsigned long long)*total_size+1, *block_size); kfree(buf); - return; } static void @@ -2009,12 +2011,13 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, { ReadCapdata_struct_16 *buf; int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); - if (buf == NULL) { + + buf = kzalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); + if (!buf) { printk(KERN_WARNING "cciss: out of memory\n"); return; } - memset(buf, 0, sizeof(ReadCapdata_struct_16)); + if (withirq) { return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16, ctlr, buf, sizeof(ReadCapdata_struct_16), @@ -2036,7 +2039,6 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, printk(KERN_INFO " blocks= %llu block_size= %d\n", (unsigned long long)*total_size+1, *block_size); kfree(buf); - return; } static int cciss_revalidate(struct gendisk *disk) @@ -2509,7 +2511,7 @@ after_error_processing: /* * Get a request and submit it to the controller. */ -static void do_cciss_request(request_queue_t *q) +static void do_cciss_request(struct request_queue *q) { ctlr_info_t *h = q->queuedata; CommandList_struct *c; @@ -3225,12 +3227,15 @@ static int alloc_cciss_hba(void) for (i = 0; i < MAX_CTLR; i++) { if (!hba[i]) { ctlr_info_t *p; + p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); if (!p) goto Enomem; p->gendisk[0] = alloc_disk(1 << NWD_SHIFT); - if (!p->gendisk[0]) + if (!p->gendisk[0]) { + kfree(p); goto Enomem; + } hba[i] = p; return i; } @@ -3378,7 +3383,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, do { drive_info_struct *drv = &(hba[i]->drv[j]); struct gendisk *disk = hba[i]->gendisk[j]; - request_queue_t *q; + struct request_queue *q; /* Check if the disk was allocated already */ if (!disk){ @@ -3521,7 +3526,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) for (j = 0; j < CISS_MAX_LUN; j++) { struct gendisk *disk = hba[i]->gendisk[j]; if (disk) { - request_queue_t *q = disk->queue; + struct request_queue *q = disk->queue; if (disk->flags & GENHD_FL_UP) del_gendisk(disk); diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 90961a8ea895..4aca7ddfdddf 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -555,7 +555,6 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) { struct scsi_cmnd *cmd; ctlr_info_t *ctlr; - u64bit addr64; ErrorInfo_struct *ei; ei = cp->err_info; @@ -569,20 +568,7 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) cmd = (struct scsi_cmnd *) cp->scsi_cmd; ctlr = hba[cp->ctlr]; - /* undo the DMA mappings */ - - if (cmd->use_sg) { - pci_unmap_sg(ctlr->pdev, - cmd->request_buffer, cmd->use_sg, - cmd->sc_data_direction); - } - else if (cmd->request_bufflen) { - addr64.val32.lower = cp->SG[0].Addr.lower; - addr64.val32.upper = cp->SG[0].Addr.upper; - pci_unmap_single(ctlr->pdev, (dma_addr_t) addr64.val, - cmd->request_bufflen, - cmd->sc_data_direction); - } + scsi_dma_unmap(cmd); cmd->result = (DID_OK << 16); /* host byte */ cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ @@ -597,7 +583,7 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) ei->SenseLen > SCSI_SENSE_BUFFERSIZE ? SCSI_SENSE_BUFFERSIZE : ei->SenseLen); - cmd->resid = ei->ResidualCnt; + scsi_set_resid(cmd, ei->ResidualCnt); if(ei->CommandStatus != 0) { /* an error has occurred */ @@ -1204,46 +1190,29 @@ cciss_scatter_gather(struct pci_dev *pdev, CommandList_struct *cp, struct scsi_cmnd *cmd) { - unsigned int use_sg, nsegs=0, len; - struct scatterlist *scatter = (struct scatterlist *) cmd->request_buffer; + unsigned int len; + struct scatterlist *sg; __u64 addr64; - - /* is it just one virtual address? */ - if (!cmd->use_sg) { - if (cmd->request_bufflen) { /* anything to xfer? */ - - addr64 = (__u64) pci_map_single(pdev, - cmd->request_buffer, - cmd->request_bufflen, - cmd->sc_data_direction); - - cp->SG[0].Addr.lower = - (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); - cp->SG[0].Addr.upper = - (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); - cp->SG[0].Len = cmd->request_bufflen; - nsegs=1; - } - } /* else, must be a list of virtual addresses.... */ - else if (cmd->use_sg <= MAXSGENTRIES) { /* not too many addrs? */ - - use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, - cmd->sc_data_direction); - - for (nsegs=0; nsegs < use_sg; nsegs++) { - addr64 = (__u64) sg_dma_address(&scatter[nsegs]); - len = sg_dma_len(&scatter[nsegs]); - cp->SG[nsegs].Addr.lower = - (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); - cp->SG[nsegs].Addr.upper = - (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); - cp->SG[nsegs].Len = len; - cp->SG[nsegs].Ext = 0; // we are not chaining + int use_sg, i; + + BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES); + + use_sg = scsi_dma_map(cmd); + if (use_sg) { /* not too many addrs? */ + scsi_for_each_sg(cmd, sg, use_sg, i) { + addr64 = (__u64) sg_dma_address(sg); + len = sg_dma_len(sg); + cp->SG[i].Addr.lower = + (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); + cp->SG[i].Addr.upper = + (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); + cp->SG[i].Len = len; + cp->SG[i].Ext = 0; // we are not chaining } - } else BUG(); + } - cp->Header.SGList = (__u8) nsegs; /* no. SGs contig in this cmd */ - cp->Header.SGTotal = (__u16) nsegs; /* total sgs in this cmd list */ + cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */ + cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */ return; } diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index b94cd1c32131..eb9799acf65b 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -161,7 +161,7 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io); -static void do_ida_request(request_queue_t *q); +static void do_ida_request(struct request_queue *q); static void start_io(ctlr_info_t *h); static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c); @@ -391,7 +391,7 @@ static void __devexit cpqarray_remove_one_eisa (int i) /* pdev is NULL for eisa */ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev) { - request_queue_t *q; + struct request_queue *q; int j; /* @@ -420,18 +420,17 @@ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev) goto Enomem2; } - hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent( + hba[i]->cmd_pool = pci_alloc_consistent( hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), &(hba[i]->cmd_pool_dhandle)); - hba[i]->cmd_pool_bits = kmalloc( - ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), + hba[i]->cmd_pool_bits = kcalloc( + (NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG, sizeof(unsigned long), GFP_KERNEL); if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool) goto Enomem1; memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t)); - memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long)); printk(KERN_INFO "cpqarray: Finding drives on %s", hba[i]->devname); @@ -886,7 +885,7 @@ static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c) * are in here (either via the dummy do_ida_request functions or by being * called from the interrupt handler */ -static void do_ida_request(request_queue_t *q) +static void do_ida_request(struct request_queue *q) { ctlr_info_t *h = q->queuedata; cmdlist_t *c; @@ -1660,45 +1659,30 @@ static void getgeometry(int ctlr) info_p->log_drv_map = 0; - id_ldrive = kmalloc(sizeof(id_log_drv_t), GFP_KERNEL); - if(id_ldrive == NULL) - { + id_ldrive = kzalloc(sizeof(id_log_drv_t), GFP_KERNEL); + if (!id_ldrive) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_0; } - id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL); - if(id_ctlr_buf == NULL) - { - kfree(id_ldrive); + id_ctlr_buf = kzalloc(sizeof(id_ctlr_t), GFP_KERNEL); + if (!id_ctlr_buf) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_1; } - id_lstatus_buf = kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL); - if(id_lstatus_buf == NULL) - { - kfree(id_ctlr_buf); - kfree(id_ldrive); + id_lstatus_buf = kzalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL); + if (!id_lstatus_buf) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_2; } - sense_config_buf = kmalloc(sizeof(config_t), GFP_KERNEL); - if(sense_config_buf == NULL) - { - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); + sense_config_buf = kzalloc(sizeof(config_t), GFP_KERNEL); + if (!sense_config_buf) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_3; } - memset(id_ldrive, 0, sizeof(id_log_drv_t)); - memset(id_ctlr_buf, 0, sizeof(id_ctlr_t)); - memset(id_lstatus_buf, 0, sizeof(sense_log_drv_stat_t)); - memset(sense_config_buf, 0, sizeof(config_t)); - info_p->phys_drives = 0; info_p->log_drv_map = 0; info_p->drv_assign_map = 0; @@ -1712,13 +1696,8 @@ static void getgeometry(int ctlr) * so the idastubopen will fail on all logical drives * on the controller. */ - /* Free all the buffers and return */ printk(KERN_ERR "cpqarray: error sending ID controller\n"); - kfree(sense_config_buf); - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); - return; + goto err_4; } info_p->log_drives = id_ctlr_buf->nr_drvs; @@ -1764,12 +1743,7 @@ static void getgeometry(int ctlr) " failed to report status of logical drive %d\n" "Access to this controller has been disabled\n", ctlr, log_unit); - /* Free all the buffers and return */ - kfree(sense_config_buf); - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); - return; + goto err_4; } /* Make sure the logical drive is configured @@ -1798,14 +1772,8 @@ static void getgeometry(int ctlr) sizeof(config_t), 0, 0, log_unit); if (ret_code == IO_ERROR) { info_p->log_drv_map = 0; - /* Free all the buffers and return */ printk(KERN_ERR "cpqarray: error sending sense config\n"); - kfree(sense_config_buf); - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); - return; - + goto err_4; } info_p->phys_drives = @@ -1820,12 +1788,18 @@ static void getgeometry(int ctlr) log_index = log_index + 1; } /* end of if logical drive configured */ } /* end of for log_unit */ + + /* Free all the buffers and return */ +err_4: kfree(sense_config_buf); - kfree(id_ldrive); +err_3: kfree(id_lstatus_buf); +err_2: kfree(id_ctlr_buf); +err_1: + kfree(id_ldrive); +err_0: return; - } static void __exit cpqarray_exit(void) diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index fe088045dd08..085b7794fb3e 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -251,7 +251,7 @@ static int irqdma_allocated; static struct request *current_req; static struct request_queue *floppy_queue; -static void do_fd_request(request_queue_t * q); +static void do_fd_request(struct request_queue * q); #ifndef fd_get_dma_residue #define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA) @@ -2981,7 +2981,7 @@ static void process_fd_request(void) schedule_bh(redo_fd_request); } -static void do_fd_request(request_queue_t * q) +static void do_fd_request(struct request_queue * q) { if (max_buffer_sectors == 0) { printk("VFS: do_fd_request called on non-open device\n"); diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 0ed5470d2533..9f015fce4135 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -68,12 +68,14 @@ #include <linux/loop.h> #include <linux/compat.h> #include <linux/suspend.h> +#include <linux/freezer.h> #include <linux/writeback.h> #include <linux/buffer_head.h> /* for invalidate_bdev() */ #include <linux/completion.h> #include <linux/highmem.h> #include <linux/gfp.h> #include <linux/kthread.h> +#include <linux/splice.h> #include <asm/uaccess.h> @@ -401,50 +403,73 @@ struct lo_read_data { }; static int -lo_read_actor(read_descriptor_t *desc, struct page *page, - unsigned long offset, unsigned long size) +lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, + struct splice_desc *sd) { - unsigned long count = desc->count; - struct lo_read_data *p = desc->arg.data; + struct lo_read_data *p = sd->u.data; struct loop_device *lo = p->lo; + struct page *page = buf->page; sector_t IV; + size_t size; + int ret; - IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); + ret = buf->ops->confirm(pipe, buf); + if (unlikely(ret)) + return ret; - if (size > count) - size = count; + IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) + + (buf->offset >> 9); + size = sd->len; + if (size > p->bsize) + size = p->bsize; - if (lo_do_transfer(lo, READ, page, offset, p->page, p->offset, size, IV)) { - size = 0; + if (lo_do_transfer(lo, READ, page, buf->offset, p->page, p->offset, size, IV)) { printk(KERN_ERR "loop: transfer error block %ld\n", page->index); - desc->error = -EINVAL; + size = -EINVAL; } flush_dcache_page(p->page); - desc->count = count - size; - desc->written += size; - p->offset += size; + if (size > 0) + p->offset += size; + return size; } static int +lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd) +{ + return __splice_from_pipe(pipe, sd, lo_splice_actor); +} + +static int do_lo_receive(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos) { struct lo_read_data cookie; + struct splice_desc sd; struct file *file; - int retval; + long retval; cookie.lo = lo; cookie.page = bvec->bv_page; cookie.offset = bvec->bv_offset; cookie.bsize = bsize; + + sd.len = 0; + sd.total_len = bvec->bv_len; + sd.flags = 0; + sd.pos = pos; + sd.u.data = &cookie; + file = lo->lo_backing_file; - retval = file->f_op->sendfile(file, &pos, bvec->bv_len, - lo_read_actor, &cookie); - return (retval < 0)? retval: 0; + retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor); + + if (retval < 0) + return retval; + + return 0; } static int @@ -504,7 +529,7 @@ static struct bio *loop_get_bio(struct loop_device *lo) return bio; } -static int loop_make_request(request_queue_t *q, struct bio *old_bio) +static int loop_make_request(struct request_queue *q, struct bio *old_bio) { struct loop_device *lo = q->queuedata; int rw = bio_rw(old_bio); @@ -533,7 +558,7 @@ out: /* * kick off io on the underlying address space */ -static void loop_unplug(request_queue_t *q) +static void loop_unplug(struct request_queue *q) { struct loop_device *lo = q->queuedata; @@ -576,13 +601,6 @@ static int loop_thread(void *data) struct loop_device *lo = data; struct bio *bio; - /* - * loop can be used in an encrypted device, - * hence, it mustn't be stopped at all - * because it could be indirectly used during suspension - */ - current->flags |= PF_NOFREEZE; - set_user_nice(current, -20); while (!kthread_should_stop() || lo->lo_bio) { @@ -679,8 +697,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file, if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) goto out_putf; - /* new backing store needs to support loop (eg sendfile) */ - if (!inode->i_fop->sendfile) + /* new backing store needs to support loop (eg splice_read) */ + if (!inode->i_fop->splice_read) goto out_putf; /* size of the new backing store needs to be the same */ @@ -760,7 +778,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, * If we can't read - sorry. If we only can't write - well, * it's going to be read-only. */ - if (!file->f_op->sendfile) + if (!file->f_op->splice_read) goto out_putf; if (aops->prepare_write && aops->commit_write) lo_flags |= LO_FLAGS_USE_AOPS; @@ -1550,8 +1568,7 @@ static void __exit loop_exit(void) loop_del_one(lo); blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range); - if (unregister_blkdev(LOOP_MAJOR, "loop")) - printk(KERN_WARNING "loop: cannot unregister blkdev\n"); + unregister_blkdev(LOOP_MAJOR, "loop"); } module_init(loop_init); diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 069ae39a9cd9..be92c658f06e 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -100,7 +100,7 @@ static const char *nbdcmd_to_ascii(int cmd) static void nbd_end_request(struct request *req) { int uptodate = (req->errors == 0) ? 1 : 0; - request_queue_t *q = req->q; + struct request_queue *q = req->q; unsigned long flags; dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name, @@ -122,17 +122,12 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, int result; struct msghdr msg; struct kvec iov; - unsigned long flags; - sigset_t oldset; + sigset_t blocked, oldset; /* Allow interception of SIGKILL only * Don't allow other signals to interrupt the transmission */ - spin_lock_irqsave(¤t->sighand->siglock, flags); - oldset = current->blocked; - sigfillset(¤t->blocked); - sigdelsetmask(¤t->blocked, sigmask(SIGKILL)); - recalc_sigpending(); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); + siginitsetinv(&blocked, sigmask(SIGKILL)); + sigprocmask(SIG_SETMASK, &blocked, &oldset); do { sock->sk->sk_allocation = GFP_NOIO; @@ -151,11 +146,9 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, if (signal_pending(current)) { siginfo_t info; - spin_lock_irqsave(¤t->sighand->siglock, flags); printk(KERN_WARNING "nbd (pid %d: %s) got signal %d\n", - current->pid, current->comm, - dequeue_signal(current, ¤t->blocked, &info)); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); + current->pid, current->comm, + dequeue_signal_lock(current, ¤t->blocked, &info)); result = -EINTR; break; } @@ -169,10 +162,7 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, buf += result; } while (size > 0); - spin_lock_irqsave(¤t->sighand->siglock, flags); - current->blocked = oldset; - recalc_sigpending(); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); + sigprocmask(SIG_SETMASK, &oldset, NULL); return result; } @@ -416,11 +406,11 @@ static void nbd_clear_que(struct nbd_device *lo) /* * We always wait for result of write, for now. It would be nice to make it optional * in future - * if ((req->cmd == WRITE) && (lo->flags & NBD_WRITE_NOCHK)) + * if ((rq_data_dir(req) == WRITE) && (lo->flags & NBD_WRITE_NOCHK)) * { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); } */ -static void do_nbd_request(request_queue_t * q) +static void do_nbd_request(struct request_queue * q) { struct request *req; diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 1eeb8f2cde71..b8a994a2b013 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -183,7 +183,7 @@ static int pcd_packet(struct cdrom_device_info *cdi, static int pcd_detect(void); static void pcd_probe_capabilities(void); static void do_pcd_read_drq(void); -static void do_pcd_request(request_queue_t * q); +static void do_pcd_request(struct request_queue * q); static void do_pcd_read(void); struct pcd_unit { @@ -713,7 +713,7 @@ static int pcd_detect(void) /* I/O request processing */ static struct request_queue *pcd_queue; -static void do_pcd_request(request_queue_t * q) +static void do_pcd_request(struct request_queue * q) { if (pcd_busy) return; diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 31e01488eb51..df819f8a95a6 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -698,7 +698,7 @@ static enum action pd_identify(struct pd_unit *disk) /* end of io request engine */ -static void do_pd_request(request_queue_t * q) +static void do_pd_request(struct request_queue * q) { if (pd_req) return; diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index 5826508f6731..ceffa6034e20 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -202,7 +202,7 @@ module_param_array(drive3, int, NULL, 0); #define ATAPI_WRITE_10 0x2a static int pf_open(struct inode *inode, struct file *file); -static void do_pf_request(request_queue_t * q); +static void do_pf_request(struct request_queue * q); static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo); @@ -760,7 +760,7 @@ static void pf_end_request(int uptodate) } } -static void do_pf_request(request_queue_t * q) +static void do_pf_request(struct request_queue * q) { if (pf_busy) return; diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index f1b9dd7d47d6..fadbfd880bab 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -146,8 +146,7 @@ static void pkt_kobj_release(struct kobject *kobj) **********************************************************/ #define DEF_ATTR(_obj,_name,_mode) \ - static struct attribute _obj = { \ - .name = _name, .owner = THIS_MODULE, .mode = _mode } + static struct attribute _obj = { .name = _name, .mode = _mode } /********************************************************** /sys/class/pktcdvd/pktcdvd[0-7]/ @@ -753,7 +752,7 @@ static inline struct bio *pkt_get_list_first(struct bio **list_head, struct bio */ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc) { - request_queue_t *q = bdev_get_queue(pd->bdev); + struct request_queue *q = bdev_get_queue(pd->bdev); struct request *rq; int ret = 0; @@ -980,7 +979,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) * Special care is needed if the underlying block device has a small * max_phys_segments value. */ -static int pkt_set_segment_merging(struct pktcdvd_device *pd, request_queue_t *q) +static int pkt_set_segment_merging(struct pktcdvd_device *pd, struct request_queue *q) { if ((pd->settings.size << 9) / CD_FRAMESIZE <= q->max_phys_segments) { /* @@ -1594,6 +1593,7 @@ static int kcdrwd(void *foobar) long min_sleep_time, residue; set_user_nice(current, -20); + set_freezable(); for (;;) { DECLARE_WAITQUEUE(wait, current); @@ -1653,9 +1653,6 @@ static int kcdrwd(void *foobar) } } - if (signal_pending(current)) { - flush_signals(current); - } if (kthread_should_stop()) break; } @@ -2317,7 +2314,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) { int ret; long lba; - request_queue_t *q; + struct request_queue *q; /* * We need to re-open the cdrom device without O_NONBLOCK to be able @@ -2480,7 +2477,7 @@ static int pkt_end_io_read_cloned(struct bio *bio, unsigned int bytes_done, int return 0; } -static int pkt_make_request(request_queue_t *q, struct bio *bio) +static int pkt_make_request(struct request_queue *q, struct bio *bio) { struct pktcdvd_device *pd; char b[BDEVNAME_SIZE]; @@ -2629,7 +2626,7 @@ end_io: -static int pkt_merge_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *bvec) +static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *bvec) { struct pktcdvd_device *pd = q->queuedata; sector_t zone = ZONE(bio->bi_sector, pd); @@ -2650,7 +2647,7 @@ static int pkt_merge_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *b static void pkt_init_queue(struct pktcdvd_device *pd) { - request_queue_t *q = pd->disk->queue; + struct request_queue *q = pd->disk->queue; blk_queue_make_request(q, pkt_make_request); blk_queue_hardsect_size(q, CD_FRAMESIZE); diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c index 688a4fb0dc99..3c796e236253 100644 --- a/drivers/block/ps2esdi.c +++ b/drivers/block/ps2esdi.c @@ -64,7 +64,7 @@ static void reset_ctrl(void); static int ps2esdi_geninit(void); -static void do_ps2esdi_request(request_queue_t * q); +static void do_ps2esdi_request(struct request_queue * q); static void ps2esdi_readwrite(int cmd, struct request *req); @@ -473,7 +473,7 @@ static void __init ps2esdi_get_device_cfg(void) } /* strategy routine that handles most of the IO requests */ -static void do_ps2esdi_request(request_queue_t * q) +static void do_ps2esdi_request(struct request_queue * q) { struct request *req; /* since, this routine is called with interrupts cleared - they diff --git a/drivers/block/rd.c b/drivers/block/rd.c index a1512da32410..65150b548f3a 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -264,7 +264,7 @@ static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec, sector_t sector, * 19-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Added devfs support * */ -static int rd_make_request(request_queue_t *q, struct bio *bio) +static int rd_make_request(struct request_queue *q, struct bio *bio) { struct block_device *bdev = bio->bi_bdev; struct address_space * mapping = bdev->bd_inode->i_mapping; diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 1a65979f1f0f..b4e462f154ea 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -225,7 +225,7 @@ static unsigned short write_postamble[] = { static void swim3_select(struct floppy_state *fs, int sel); static void swim3_action(struct floppy_state *fs, int action); static int swim3_readbit(struct floppy_state *fs, int bit); -static void do_fd_request(request_queue_t * q); +static void do_fd_request(struct request_queue * q); static void start_request(struct floppy_state *fs); static void set_timeout(struct floppy_state *fs, int nticks, void (*proc)(unsigned long)); @@ -290,7 +290,7 @@ static int swim3_readbit(struct floppy_state *fs, int bit) return (stat & DATA) == 0; } -static void do_fd_request(request_queue_t * q) +static void do_fd_request(struct request_queue * q) { int i; for(i=0;i<floppy_count;i++) diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 54509eb3391b..402209fec59a 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -278,7 +278,7 @@ struct carm_host { unsigned int state; u32 fw_ver; - request_queue_t *oob_q; + struct request_queue *oob_q; unsigned int n_oob; unsigned int hw_sg_used; @@ -287,7 +287,7 @@ struct carm_host { unsigned int wait_q_prod; unsigned int wait_q_cons; - request_queue_t *wait_q[CARM_MAX_WAIT_Q]; + struct request_queue *wait_q[CARM_MAX_WAIT_Q]; unsigned int n_msgs; u64 msg_alloc; @@ -756,7 +756,7 @@ static inline void carm_end_request_queued(struct carm_host *host, assert(rc == 0); } -static inline void carm_push_q (struct carm_host *host, request_queue_t *q) +static inline void carm_push_q (struct carm_host *host, struct request_queue *q) { unsigned int idx = host->wait_q_prod % CARM_MAX_WAIT_Q; @@ -768,7 +768,7 @@ static inline void carm_push_q (struct carm_host *host, request_queue_t *q) BUG_ON(host->wait_q_prod == host->wait_q_cons); /* overrun */ } -static inline request_queue_t *carm_pop_q(struct carm_host *host) +static inline struct request_queue *carm_pop_q(struct carm_host *host) { unsigned int idx; @@ -783,7 +783,7 @@ static inline request_queue_t *carm_pop_q(struct carm_host *host) static inline void carm_round_robin(struct carm_host *host) { - request_queue_t *q = carm_pop_q(host); + struct request_queue *q = carm_pop_q(host); if (q) { blk_start_queue(q); VPRINTK("STARTED QUEUE %p\n", q); @@ -802,7 +802,7 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, } } -static void carm_oob_rq_fn(request_queue_t *q) +static void carm_oob_rq_fn(struct request_queue *q) { struct carm_host *host = q->queuedata; struct carm_request *crq; @@ -833,7 +833,7 @@ static void carm_oob_rq_fn(request_queue_t *q) } } -static void carm_rq_fn(request_queue_t *q) +static void carm_rq_fn(struct request_queue *q) { struct carm_port *port = q->queuedata; struct carm_host *host = port->host; @@ -1494,7 +1494,7 @@ static int carm_init_disks(struct carm_host *host) for (i = 0; i < CARM_MAX_PORTS; i++) { struct gendisk *disk; - request_queue_t *q; + struct request_queue *q; struct carm_port *port; port = &host->port[i]; @@ -1538,7 +1538,7 @@ static void carm_free_disks(struct carm_host *host) for (i = 0; i < CARM_MAX_PORTS; i++) { struct gendisk *disk = host->port[i].disk; if (disk) { - request_queue_t *q = disk->queue; + struct request_queue *q = disk->queue; if (disk->flags & GENHD_FL_UP) del_gendisk(disk); @@ -1571,7 +1571,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) struct carm_host *host; unsigned int pci_dac; int rc; - request_queue_t *q; + struct request_queue *q; unsigned int i; if (!printed_version++) @@ -1608,7 +1608,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) } #endif - host = kmalloc(sizeof(*host), GFP_KERNEL); + host = kzalloc(sizeof(*host), GFP_KERNEL); if (!host) { printk(KERN_ERR DRV_NAME "(%s): memory alloc failure\n", pci_name(pdev)); @@ -1616,7 +1616,6 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_regions; } - memset(host, 0, sizeof(*host)); host->pdev = pdev; host->flags = pci_dac ? FL_DAC : 0; spin_lock_init(&host->lock); diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 746a118a9b52..c57dd2b3a0c8 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -503,7 +503,7 @@ static void ub_cleanup(struct ub_dev *sc) { struct list_head *p; struct ub_lun *lun; - request_queue_t *q; + struct request_queue *q; while (!list_empty(&sc->luns)) { p = sc->luns.next; @@ -619,7 +619,7 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc) * The request function is our main entry point */ -static void ub_request_fn(request_queue_t *q) +static void ub_request_fn(struct request_queue *q) { struct ub_lun *lun = q->queuedata; struct request *rq; @@ -1547,10 +1547,8 @@ static void ub_reset_enter(struct ub_dev *sc, int try) #endif #if 0 /* We let them stop themselves. */ - struct list_head *p; struct ub_lun *lun; - list_for_each(p, &sc->luns) { - lun = list_entry(p, struct ub_lun, link); + list_for_each_entry(lun, &sc->luns, link) { blk_stop_queue(lun->disk->queue); } #endif @@ -1562,7 +1560,6 @@ static void ub_reset_task(struct work_struct *work) { struct ub_dev *sc = container_of(work, struct ub_dev, reset_work); unsigned long flags; - struct list_head *p; struct ub_lun *lun; int lkr, rc; @@ -1608,8 +1605,7 @@ static void ub_reset_task(struct work_struct *work) spin_lock_irqsave(sc->lock, flags); sc->reset = 0; tasklet_schedule(&sc->tasklet); - list_for_each(p, &sc->luns) { - lun = list_entry(p, struct ub_lun, link); + list_for_each_entry(lun, &sc->luns, link) { blk_start_queue(lun->disk->queue); } wake_up(&sc->reset_wait); @@ -1713,7 +1709,7 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp, struct gendisk *disk = inode->i_bdev->bd_disk; void __user *usermem = (void __user *) arg; - return scsi_cmd_ioctl(filp, disk, cmd, usermem); + return scsi_cmd_ioctl(filp, disk->queue, disk, cmd, usermem); } /* @@ -2277,7 +2273,7 @@ err_core: static int ub_probe_lun(struct ub_dev *sc, int lnum) { struct ub_lun *lun; - request_queue_t *q; + struct request_queue *q; struct gendisk *disk; int rc; @@ -2348,7 +2344,6 @@ err_alloc: static void ub_disconnect(struct usb_interface *intf) { struct ub_dev *sc = usb_get_intfdata(intf); - struct list_head *p; struct ub_lun *lun; unsigned long flags; @@ -2403,8 +2398,7 @@ static void ub_disconnect(struct usb_interface *intf) /* * Unregister the upper layer. */ - list_for_each (p, &sc->luns) { - lun = list_entry(p, struct ub_lun, link); + list_for_each_entry(lun, &sc->luns, link) { del_gendisk(lun->disk); /* * I wish I could do: diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 6f5d6203d725..6b7c02d6360d 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -105,12 +105,6 @@ struct cardinfo { unsigned long csr_base; unsigned char __iomem *csr_remap; unsigned long csr_len; -#ifdef CONFIG_MM_MAP_MEMORY - unsigned long mem_base; - unsigned char __iomem *mem_remap; - unsigned long mem_len; -#endif - unsigned int win_size; /* PCI window size */ unsigned int mm_size; /* size in kbytes */ @@ -120,7 +114,7 @@ struct cardinfo { */ struct bio *bio, *currentbio, **biotail; - request_queue_t *queue; + struct request_queue *queue; struct mm_page { dma_addr_t page_dma; @@ -363,7 +357,7 @@ static inline void reset_page(struct mm_page *page) page->biotail = & page->bio; } -static void mm_unplug_device(request_queue_t *q) +static void mm_unplug_device(struct request_queue *q) { struct cardinfo *card = q->queuedata; unsigned long flags; @@ -547,7 +541,7 @@ static void process_page(unsigned long data) -- mm_make_request ----------------------------------------------------------------------------------- */ -static int mm_make_request(request_queue_t *q, struct bio *bio) +static int mm_make_request(struct request_queue *q, struct bio *bio) { struct cardinfo *card = q->queuedata; pr_debug("mm_make_request %llu %u\n", @@ -872,10 +866,6 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i card->csr_base = pci_resource_start(dev, 0); card->csr_len = pci_resource_len(dev, 0); -#ifdef CONFIG_MM_MAP_MEMORY - card->mem_base = pci_resource_start(dev, 1); - card->mem_len = pci_resource_len(dev, 1); -#endif printk(KERN_INFO "Micro Memory(tm) controller #%d found at %02x:%02x (PCI Mem Module (Battery Backup))\n", card->card_number, dev->bus->number, dev->devfn); @@ -903,27 +893,6 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i printk(KERN_INFO "MM%d: CSR 0x%08lx -> 0x%p (0x%lx)\n", card->card_number, card->csr_base, card->csr_remap, card->csr_len); -#ifdef CONFIG_MM_MAP_MEMORY - if (!request_mem_region(card->mem_base, card->mem_len, "Micro Memory")) { - printk(KERN_ERR "MM%d: Unable to request memory region\n", card->card_number); - ret = -ENOMEM; - - goto failed_req_mem; - } - - if (!(card->mem_remap = ioremap(card->mem_base, cards->mem_len))) { - printk(KERN_ERR "MM%d: Unable to remap memory region\n", card->card_number); - ret = -ENOMEM; - - goto failed_remap_mem; - } - - printk(KERN_INFO "MM%d: MEM 0x%8lx -> 0x%8lx (0x%lx)\n", card->card_number, - card->mem_base, card->mem_remap, card->mem_len); -#else - printk(KERN_INFO "MM%d: MEM area not remapped (CONFIG_MM_MAP_MEMORY not set)\n", - card->card_number); -#endif switch(card->dev->device) { case 0x5415: card->flags |= UM_FLAG_NO_BYTE_STATUS | UM_FLAG_NO_BATTREG; @@ -1091,12 +1060,6 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i card->mm_pages[1].desc, card->mm_pages[1].page_dma); failed_magic: -#ifdef CONFIG_MM_MAP_MEMORY - iounmap(card->mem_remap); - failed_remap_mem: - release_mem_region(card->mem_base, card->mem_len); - failed_req_mem: -#endif iounmap(card->csr_remap); failed_remap_csr: release_mem_region(card->csr_base, card->csr_len); @@ -1116,10 +1079,6 @@ static void mm_pci_remove(struct pci_dev *dev) tasklet_kill(&card->tasklet); iounmap(card->csr_remap); release_mem_region(card->csr_base, card->csr_len); -#ifdef CONFIG_MM_MAP_MEMORY - iounmap(card->mem_remap); - release_mem_region(card->mem_base, card->mem_len); -#endif free_irq(card->irq, card); if (card->mm_pages[0].desc) @@ -1133,23 +1092,18 @@ static void mm_pci_remove(struct pci_dev *dev) blk_cleanup_queue(card->queue); } -static const struct pci_device_id mm_pci_ids[] = { { - .vendor = PCI_VENDOR_ID_MICRO_MEMORY, - .device = PCI_DEVICE_ID_MICRO_MEMORY_5415CN, - }, { - .vendor = PCI_VENDOR_ID_MICRO_MEMORY, - .device = PCI_DEVICE_ID_MICRO_MEMORY_5425CN, - }, { - .vendor = PCI_VENDOR_ID_MICRO_MEMORY, - .device = PCI_DEVICE_ID_MICRO_MEMORY_6155, - }, { +static const struct pci_device_id mm_pci_ids[] = { + {PCI_DEVICE(PCI_VENDOR_ID_MICRO_MEMORY,PCI_DEVICE_ID_MICRO_MEMORY_5415CN)}, + {PCI_DEVICE(PCI_VENDOR_ID_MICRO_MEMORY,PCI_DEVICE_ID_MICRO_MEMORY_5425CN)}, + {PCI_DEVICE(PCI_VENDOR_ID_MICRO_MEMORY,PCI_DEVICE_ID_MICRO_MEMORY_6155)}, + { .vendor = 0x8086, .device = 0xB555, .subvendor= 0x1332, .subdevice= 0x5460, .class = 0x050000, .class_mask= 0, - }, { /* end: all zeroes */ } + }, { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE(pci, mm_pci_ids); diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index 68592c336011..af3969a9c963 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -41,7 +41,6 @@ #include <linux/dma-mapping.h> #include <linux/completion.h> #include <linux/device.h> -#include <linux/kernel.h> #include <asm/uaccess.h> #include <asm/vio.h> @@ -252,10 +251,10 @@ static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) struct gendisk *disk = bdev->bd_disk; struct viodasd_device *d = disk->private_data; - geo->sectors = d->sectors ? d->sectors : 0; + geo->sectors = d->sectors ? d->sectors : 32; geo->heads = d->tracks ? d->tracks : 64; geo->cylinders = d->cylinders ? d->cylinders : - get_capacity(disk) / (geo->cylinders * geo->heads); + get_capacity(disk) / (geo->sectors * geo->heads); return 0; } @@ -400,7 +399,7 @@ error_ret: /* * This is the external request processing routine */ -static void do_viodasd_request(request_queue_t *q) +static void do_viodasd_request(struct request_queue *q) { struct request *req; diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 0d97b7eb818a..624d30f7da3f 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -298,7 +298,7 @@ static u_char __init xd_detect (u_char *controller, unsigned int *address) } /* do_xd_request: handle an incoming request */ -static void do_xd_request (request_queue_t * q) +static void do_xd_request (struct request_queue * q) { struct request *req; diff --git a/drivers/block/xd.h b/drivers/block/xd.h index 82e090fea957..cffd44a20383 100644 --- a/drivers/block/xd.h +++ b/drivers/block/xd.h @@ -104,7 +104,7 @@ static int xd_manual_geo_init (char *command); static u_char xd_detect (u_char *controller, unsigned int *address); static u_char xd_initdrives (void (*init_drive)(u_char drive)); -static void do_xd_request (request_queue_t * q); +static void do_xd_request (struct request_queue * q); static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg); static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count); static void xd_recalibrate (u_char drive); diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 7cc2685ca84a..2d5853cbd4b0 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -44,9 +44,6 @@ extern int m68k_realnum_memory; extern struct mem_info m68k_memory[NUM_MEMINFO]; -#define TRUE (1) -#define FALSE (0) - #define Z2MINOR_COMBINED (0) #define Z2MINOR_Z2ONLY (1) #define Z2MINOR_CHIPONLY (2) @@ -70,7 +67,7 @@ static DEFINE_SPINLOCK(z2ram_lock); static struct block_device_operations z2_fops; static struct gendisk *z2ram_gendisk; -static void do_z2_request(request_queue_t *q) +static void do_z2_request(struct request_queue *q) { struct request *req; while ((req = elv_next_request(q)) != NULL) { @@ -374,9 +371,7 @@ static void __exit z2_exit(void) { int i, j; blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256); - if ( unregister_blkdev( Z2RAM_MAJOR, DEVICE_NAME ) != 0 ) - printk( KERN_ERR DEVICE_NAME ": unregister of device failed\n"); - + unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME); del_gendisk(z2ram_gendisk); put_disk(z2ram_gendisk); blk_cleanup_queue(z2_queue); |