Commit 10e294df authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s/390 patches for 2.5.20 (3 of 4).

Third patch of the s/390 update. Everything from drivers/s390. This patch
contains the main bunch of changes. Major changes are: 1) the restructured
dasd driver, 2) the new tape driver, 3) the start of the common io layer
rework, 4) the gpl'ed lcs driver and 5) the gpl'ed qdio layer
parent e105d28a
......@@ -321,6 +321,18 @@ CONFIG_DASD_CKD
CONFIG_DASD_FBA
FBA devices are currently unsupported.
CONFIG_DASD_AUTO_DIAG
Enable this option if you want your DIAG discipline module loaded
on DASD driver startup.
CONFIG_DASD_AUTO_ECKD
Enable this option if you want your ECKD discipline module loaded
on DASD driver startup.
CONFIG_DASD_AUTO_FBA
Enable this option if you want your FBA discipline module loaded
on DASD driver startup.
CONFIG_TN3215
Include support for IBM 3215 line-mode terminals.
......@@ -343,6 +355,15 @@ CONFIG_HWC_CONSOLE
Include support for using an IBM HWC line-mode terminal as the Linux
system console.
CONFIG_HWC_CPI
This option enables the hardware console interface for system
identification This is commonly used for workload management and
gives you a nice name for the system on the service element.
Please select this option as a module since built-in operation is
completely untested.
You should only select this option if you know what you are doing,
need this feature and intend to run your kernel in LPAR.
CONFIG_S390_TAPE
Select this option if you want to access channel-attached tape
devices on IBM S/390 or zSeries.
......
......@@ -63,8 +63,8 @@ if [ "$CONFIG_S390_TAPE" != "n" ]; then
bool ' Support for tape character devices' CONFIG_S390_TAPE_CHAR
bool ' Support for tape block devices' CONFIG_S390_TAPE_BLOCK
comment 'S/390 tape hardware support'
bool ' Support for 3490 tape hardware' CONFIG_S390_TAPE_3490
bool ' Support for 3480 tape hardware' CONFIG_S390_TAPE_3480
dep_tristate ' Support for 3490 tape hardware' CONFIG_S390_TAPE_3490 $CONFIG_S390_TAPE
dep_tristate ' Support for 3480 tape hardware' CONFIG_S390_TAPE_3480 $CONFIG_S390_TAPE
fi
endmenu
......@@ -87,6 +87,10 @@ if [ "$CONFIG_NET" = "y" ]; then
define_bool CONFIG_HOTPLUG y
fi
if [ "$CONFIG_NET_ETHERNET" != "n" -o "$CONFIG_TR" != "n" ]; then
tristate 'Lan Channel Station Interface' CONFIG_LCS
fi
tristate 'CTC device support' CONFIG_CTC
tristate 'IUCV device support (VM only)' CONFIG_IUCV
fi
......
......@@ -2,11 +2,14 @@
# Makefile for the S/390 specific device drivers
#
mod-subdirs := block char misc net
mod-subdirs := block char misc net scsi cio
export-objs += ccwcache.o idals.o s390dyn.o s390io.o
export-objs += s390dyn.o
obj-y += s390io.o s390mach.o s390dyn.o idals.o ccwcache.o
obj-y += block/ char/ misc/ net/
obj-$(CONFIG_QDIO) += qdio.o
export-objs += qdio.o
obj-y += s390mach.o s390dyn.o sysinfo.o
obj-y += block/ char/ misc/ net/ scsi/ cio/
include $(TOPDIR)/Rules.make
......@@ -2,12 +2,13 @@
# S/390 block devices
#
export-objs := dasd.o
export-objs := dasd.o dasd_devmap.o dasd_ioctl.o dasd_erp.o
dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o
dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o
dasd_diag_mod-objs := dasd_diag.o
dasd_mod-objs := dasd.o
dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \
dasd_genhd.o dasd_erp.o
obj-$(CONFIG_DASD) += dasd_mod.o
obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o
......
This diff is collapsed.
......@@ -5,14 +5,10 @@
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
*/
#include <asm/ccwcache.h>
#define PRINTK_HEADER "dasd_erp(3370)"
#include "dasd_int.h"
#include "dasd_3370_erp.h"
#ifdef PRINTK_HEADER
#undef PRINTK_HEADER
#define PRINTK_HEADER "dasd_erp(3370)"
#endif /* PRINTK_HEADER */
/*
* DASD_3370_ERP_EXAMINE
......@@ -26,19 +22,19 @@
* 'Chapter 7. 3370 Sense Data'.
*
* RETURN VALUES
* dasd_era_none no error
* dasd_era_fatal for all fatal (unrecoverable errors)
* dasd_era_recover for all others.
* dasd_era_none no error
* dasd_era_fatal for all fatal (unrecoverable errors)
* dasd_era_recover for all others.
*/
dasd_era_t
dasd_3370_erp_examine (ccw_req_t * cqr, devstat_t * stat)
dasd_era_t
dasd_3370_erp_examine(dasd_ccw_req_t * cqr, devstat_t * stat)
{
char *sense = stat->ii.sense.data;
/* check for successful execution first */
if (stat->cstat == 0x00 &&
stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
return dasd_era_none;
return dasd_era_none;
if (sense[0] & 0x80) { /* CMD reject */
return dasd_era_fatal;
}
......@@ -100,7 +96,7 @@ dasd_3370_erp_examine (ccw_req_t * cqr, devstat_t * stat)
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* indent-tabs-mode: nil
* indent-tabs-mode: 1
* tab-width: 8
* End:
*/
......@@ -10,6 +10,6 @@
#ifndef DASD_3370_ERP_H
#define DASD_3370_ERP_H
dasd_era_t dasd_3370_erp_examine (ccw_req_t *, devstat_t *);
dasd_era_t dasd_3370_erp_examine(dasd_ccw_req_t *, devstat_t *);
#endif /* DASD_3990_ERP_H */
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -10,16 +10,16 @@
#ifndef DASD_3990_ERP_H
#define DASD_3990_ERP_H
dasd_era_t dasd_3990_erp_examine (ccw_req_t *, devstat_t *);
dasd_era_t dasd_3990_erp_examine(dasd_ccw_req_t *, devstat_t *);
ccw_req_t *dasd_3990_erp_action (ccw_req_t *);
ccw_req_t *dasd_2105_erp_action (ccw_req_t *);
dasd_ccw_req_t *dasd_3990_erp_action(dasd_ccw_req_t *);
dasd_ccw_req_t *dasd_2105_erp_action(ccw_req_t *);
void dasd_3990_erp_restart_queue (unsigned long);
void dasd_3990_erp_restart_queue(unsigned long);
typedef struct DCTL_data_t {
unsigned char subcommand; /* e.g Inhibit Write, Enable Write,... */
unsigned char modifier; /* Subcommand modifier */
unsigned char modifier; /* Subcommand modifier */
unsigned short res; /* reserved */
} __attribute__ ((packed)) DCTL_data_t;
......
......@@ -5,14 +5,10 @@
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
*/
#include <asm/ccwcache.h>
#define PRINTK_HEADER "dasd_erp(9336)"
#include "dasd_int.h"
#include "dasd_9336_erp.h"
#ifdef PRINTK_HEADER
#undef PRINTK_HEADER
#define PRINTK_HEADER "dasd_erp(9336)"
#endif /* PRINTK_HEADER */
/*
* DASD_9336_ERP_EXAMINE
......@@ -26,16 +22,17 @@
* 'Chapter 7. 9336 Sense Data'.
*
* RETURN VALUES
* dasd_era_none no error
* dasd_era_fatal for all fatal (unrecoverable errors)
* dasd_era_recover for all others.
* dasd_era_none no error
* dasd_era_fatal for all fatal (unrecoverable errors)
* dasd_era_recover for all others.
*/
dasd_era_t dasd_9336_erp_examine (ccw_req_t * cqr, devstat_t * stat)
dasd_era_t
dasd_9336_erp_examine(dasd_ccw_req_t * cqr, devstat_t * stat)
{
/* check for successful execution first */
if (stat->cstat == 0x00 &&
stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
return dasd_era_none;
return dasd_era_none;
/* examine the 24 byte sense data */
return dasd_era_recover;
......@@ -56,7 +53,7 @@ dasd_era_t dasd_9336_erp_examine (ccw_req_t * cqr, devstat_t * stat)
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* indent-tabs-mode: nil
* indent-tabs-mode: 1
* tab-width: 8
* End:
*/
......@@ -10,6 +10,6 @@
#ifndef DASD_9336_ERP_H
#define DASD_9336_ERP_H
dasd_era_t dasd_9336_erp_examine (ccw_req_t *, devstat_t *);
dasd_era_t dasd_9336_erp_examine(dasd_ccw_req_t *, devstat_t *);
#endif /* DASD_3990_ERP_H */
......@@ -5,18 +5,15 @@
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
*/
#include <asm/ccwcache.h>
#include "dasd_int.h"
#ifdef PRINTK_HEADER
#undef PRINTK_HEADER
#define PRINTK_HEADER "dasd_erp(9343)"
#endif /* PRINTK_HEADER */
dasd_era_t dasd_9343_erp_examine (ccw_req_t * cqr, devstat_t * stat)
#include "dasd_int.h"
dasd_era_t
dasd_9343_erp_examine(dasd_ccw_req_t * cqr, devstat_t * stat)
{
if (stat->cstat == 0x00 &&
stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
return dasd_era_none;
return dasd_era_none;
return dasd_era_recover;
}
......@@ -10,8 +10,8 @@
#ifndef DASD_9343_ERP_H
#define DASD_9343_ERP_H
dasd_era_t dasd_9343_erp_examine (ccw_req_t *, devstat_t *);
dasd_era_t dasd_9343_erp_examine(dasd_ccw_req_t *, devstat_t *);
ccw_req_t *dasd_9343_erp_action (ccw_req_t *);
dasd_ccw_req_t *dasd_9343_erp_action(dasd_ccw_req_t *);
#endif /* DASD_9343_ERP_H */
This diff is collapsed.
This diff is collapsed.
......@@ -10,13 +10,12 @@
#define MDSK_WRITE_REQ 0x01
#define MDSK_READ_REQ 0x02
#define INIT_BIO 0x00
#define RW_BIO 0x01
#define TERM_BIO 0x02
#define INIT_BIO 0x00
#define RW_BIO 0x01
#define TERM_BIO 0x02
#define DEV_CLASS_FBA 0x01
#define DEV_CLASS_ECKD 0x04
#define DEV_CLASS_CKD 0x04
#define DEV_CLASS_FBA 0x01
#define DEV_CLASS_ECKD 0x04
typedef struct dasd_diag_characteristics_t {
u16 dev_nr;
......@@ -29,7 +28,7 @@ typedef struct dasd_diag_characteristics_t {
u8 rdev_type;
u8 rdev_model;
u8 rdev_features;
} __attribute__ ((packed, aligned (4)))
} __attribute__ ((packed, aligned(4)))
dasd_diag_characteristics_t;
......@@ -40,7 +39,7 @@ typedef struct diag_bio_t {
u32 block_number;
u32 alet;
u32 buffer;
} __attribute__ ((packed, aligned (8)))
} __attribute__ ((packed, aligned(8)))
diag_bio_t;
......@@ -52,7 +51,7 @@ typedef struct diag_init_io_t {
u32 start_block;
u32 end_block;
u32 spare2[6];
} __attribute__ ((packed, aligned (8)))
} __attribute__ ((packed, aligned(8)))
diag_init_io_t;
......@@ -67,9 +66,9 @@ typedef struct diag_rw_io_t {
u32 bio_list;
u32 interrupt_params;
u32 spare3[5];
} __attribute__ ((packed, aligned (8)))
} __attribute__ ((packed, aligned(8)))
diag_rw_io_t;
int dasd_diag_init (void);
void dasd_diag_cleanup (void);
int dasd_diag_init(void);
void dasd_diag_cleanup(void);
This diff is collapsed.
#ifndef DASD_ECKD_H
#define DASD_ECKD_H
#include "dasd_3990_erp.h"
#include "dasd_9343_erp.h"
#define DASD_ECKD_CCW_WRITE 0x05
#define DASD_ECKD_CCW_READ 0x06
/*******************************************************************************
* SECTION: CCW Definitions
******************************************************************************/
#define DASD_ECKD_CCW_WRITE 0x05
#define DASD_ECKD_CCW_READ 0x06
#define DASD_ECKD_CCW_WRITE_HOME_ADDRESS 0x09
#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a
#define DASD_ECKD_CCW_WRITE_KD 0x0d
#define DASD_ECKD_CCW_READ_KD 0x0e
#define DASD_ECKD_CCW_ERASE 0x11
#define DASD_ECKD_CCW_READ_COUNT 0x12
#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15
#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16
#define DASD_ECKD_CCW_WRITE_CKD 0x1d
#define DASD_ECKD_CCW_READ_CKD 0x1e
#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
#define DASD_ECKD_CCW_DEFINE_EXTENT 0x63
#define DASD_ECKD_CCW_WRITE_MT 0x85
#define DASD_ECKD_CCW_READ_MT 0x86
#define DASD_ECKD_CCW_WRITE_KD_MT 0x8d
#define DASD_ECKD_CCW_READ_KD_MT 0x8e
#define DASD_ECKD_CCW_RELEASE 0x94
#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
#define DASD_ECKD_CCW_RESERVE 0xB4
#define DASD_ECKD_CCW_SLCK 0x14 /* steal lock - unconditional reserve */
#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a
#define DASD_ECKD_CCW_WRITE_KD 0x0d
#define DASD_ECKD_CCW_READ_KD 0x0e
#define DASD_ECKD_CCW_ERASE 0x11
#define DASD_ECKD_CCW_READ_COUNT 0x12
#define DASD_ECKD_CCW_SLCK 0x14
#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15
#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16
#define DASD_ECKD_CCW_WRITE_CKD 0x1d
#define DASD_ECKD_CCW_READ_CKD 0x1e
#define DASD_ECKD_CCW_PSF 0x27
#define DASD_ECKD_CCW_RSSD 0x3e
#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
#define DASD_ECKD_CCW_DEFINE_EXTENT 0x63
#define DASD_ECKD_CCW_WRITE_MT 0x85
#define DASD_ECKD_CCW_READ_MT 0x86
#define DASD_ECKD_CCW_WRITE_KD_MT 0x8d
#define DASD_ECKD_CCW_READ_KD_MT 0x8e
#define DASD_ECKD_CCW_RELEASE 0x94
#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
#define DASD_ECKD_CCW_RESERVE 0xB4
/*
*Perform Subsystem Function / Sub-Orders
*/
#define PSF_ORDER_PRSSD 0x18
typedef
struct eckd_count_t {
/*******************************************************************************
* SECTION: Type Definitions
******************************************************************************/
typedef struct eckd_count_t {
__u16 cyl;
__u16 head;
__u8 record;
__u8 kl;
__u16 dl;
} __attribute__ ((packed))
eckd_count_t;
} __attribute__ ((packed)) eckd_count_t;
typedef
struct ch_t {
typedef struct ch_t {
__u16 cyl;
__u16 head;
} __attribute__ ((packed))
} __attribute__ ((packed)) ch_t;
ch_t;
typedef
struct chs_t {
typedef struct chs_t {
__u16 cyl;
__u16 head;
__u32 sector;
} __attribute__ ((packed))
chs_t;
} __attribute__ ((packed)) chs_t;
typedef
struct chr_t {
typedef struct chr_t {
__u16 cyl;
__u16 head;
__u8 record;
} __attribute__ ((packed))
chr_t;
} __attribute__ ((packed)) chr_t;
typedef
struct geom_t {
typedef struct geom_t {
__u16 cyl;
__u16 head;
__u32 sector;
} __attribute__ ((packed))
geom_t;
} __attribute__ ((packed)) geom_t;
typedef struct eckd_home_t {
__u8 skip_control[14];
......@@ -83,12 +79,9 @@ typedef struct eckd_home_t {
__u8 reserved;
__u8 key_length;
__u8 reserved2[2];
} __attribute__ ((packed))
eckd_home_t;
} __attribute__ ((packed)) eckd_home_t;
typedef
struct DE_eckd_data_t {
typedef struct DE_eckd_data_t {
struct {
unsigned char perm:2; /* Permissions on this extent */
unsigned char reserved:1;
......@@ -105,16 +98,13 @@ typedef
} __attribute__ ((packed)) attributes;
__u16 short blk_size; /* Blocksize */
__u16 fast_write_id;
__u8 unused;
__u8 reserved;
__u8 ga_additional; /* Global Attributes Additional */
__u8 ga_extended; /* Global Attributes Extended */
ch_t beg_ext;
ch_t end_ext;
} __attribute__ ((packed))
} __attribute__ ((packed)) DE_eckd_data_t;
DE_eckd_data_t;
typedef
struct LO_eckd_data_t {
typedef struct LO_eckd_data_t {
struct {
unsigned char orientation:2;
unsigned char operation:6;
......@@ -130,12 +120,9 @@ typedef
chr_t search_arg;
__u8 sector;
__u16 length;
} __attribute__ ((packed))
LO_eckd_data_t;
} __attribute__ ((packed)) LO_eckd_data_t;
typedef
struct dasd_eckd_characteristics_t {
typedef struct dasd_eckd_characteristics_t {
__u16 cu_type;
struct {
unsigned char support:2;
......@@ -205,9 +192,7 @@ typedef
__u8 factor8;
__u8 reserved2[3];
__u8 reserved3[10];
} __attribute__ ((packed))
dasd_eckd_characteristics_t;
} __attribute__ ((packed)) dasd_eckd_characteristics_t;
typedef struct dasd_eckd_confdata_t {
struct {
......@@ -324,10 +309,19 @@ typedef struct dasd_eckd_confdata_t {
__u8 log_dev_address;
unsigned char reserved2[12];
} __attribute__ ((packed)) neq;
} __attribute__ ((packed))
} __attribute__ ((packed)) dasd_eckd_confdata_t;
dasd_eckd_confdata_t;
/*
* Perform Subsystem Function - Prepare for Read Subsystem Data
*/
typedef struct dasd_psf_prssd_data_t {
unsigned char order;
unsigned char flags;
unsigned char reserved[4];
unsigned char suborder;
unsigned char varies[9];
} __attribute__ ((packed)) dasd_psf_prssd_data_t;
int dasd_eckd_init (void);
void dasd_eckd_cleanup (void);
int dasd_eckd_init(void);
void dasd_eckd_cleanup(void);
#endif /* DASD_ECKD_H */
/*
* File...........: linux/drivers/s390/block/dasd.c
* Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
* Horst Hummel <Horst.Hummel@de.ibm.com>
* Carsten Otte <Cotte@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
*
* 05/04/02 split from dasd.c, code restructuring.
*/
#include <linux/config.h>
#include <linux/version.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <asm/debug.h>
#include <asm/ebcdic.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
/* This is ugly... */
#define PRINTK_HEADER "dasd_erp:"
#include "dasd_int.h"
dasd_ccw_req_t *
dasd_alloc_erp_request(char *magic, int cplength, int datasize,
dasd_device_t * device)
{
unsigned long flags;
dasd_ccw_req_t *cqr;
char *data;
int size;
/* Sanity checks */
if ( magic == NULL || datasize > PAGE_SIZE ||
(cplength*sizeof(ccw1_t)) > PAGE_SIZE)
BUG();
debug_text_event ( dasd_debug_area, 1, "ALLC");
debug_text_event ( dasd_debug_area, 1, magic);
debug_int_event ( dasd_debug_area, 1, cplength);
debug_int_event ( dasd_debug_area, 1, datasize);
size = (sizeof(dasd_ccw_req_t) + 7L) & -8L;
if (cplength > 0)
size += cplength * sizeof(ccw1_t);
if (datasize > 0)
size += datasize;
spin_lock_irqsave(&device->mem_lock, flags);
cqr = (dasd_ccw_req_t *) dasd_alloc_chunk(&device->erp_chunks, size);
spin_unlock_irqrestore(&device->mem_lock, flags);
if (cqr == NULL)
return ERR_PTR(-ENOMEM);
memset(cqr, 0, sizeof(dasd_ccw_req_t));
data = (char *) cqr + ((sizeof(dasd_ccw_req_t) + 7L) & -8L);
cqr->cpaddr = NULL;
if (cplength > 0) {
cqr->cpaddr = (ccw1_t *) data;
data += cplength*sizeof(ccw1_t);
memset(cqr->cpaddr, 0, cplength*sizeof(ccw1_t));
}
cqr->data = NULL;
if (datasize > 0) {
cqr->data = data;
memset(cqr->data, 0, datasize);
}
strncpy((char *) &cqr->magic, magic, 4);
ASCEBC((char *) &cqr->magic, 4);
atomic_inc(&device->ref_count);
return cqr;
}
void
dasd_free_erp_request(dasd_ccw_req_t * cqr, dasd_device_t * device)
{
unsigned long flags;
if (cqr->dstat != NULL)
kfree(cqr->dstat);
debug_text_event(dasd_debug_area, 1, "FREE");
debug_int_event(dasd_debug_area, 1, (long) cqr);
spin_lock_irqsave(&device->mem_lock, flags);
dasd_free_chunk(&device->erp_chunks, cqr);
spin_unlock_irqrestore(&device->mem_lock, flags);
atomic_dec(&device->ref_count);
}
/*
* DESCRIPTION
* sets up the default-ERP dasd_ccw_req_t, namely one, which performs a TIC
* to the original channel program with a retry counter of 16
*
* PARAMETER
* cqr failed CQR
*
* RETURN VALUES
* erp CQR performing the ERP
*/
dasd_ccw_req_t *
dasd_default_erp_action(dasd_ccw_req_t * cqr)
{
dasd_device_t *device;
dasd_ccw_req_t *erp;
MESSAGE(KERN_DEBUG, "%s", "Default ERP called... ");
device = cqr->device;
erp = dasd_alloc_erp_request((char *) &cqr->magic, 1, 0, device);
if (IS_ERR(erp)) {
DEV_MESSAGE(KERN_ERR, device, "%s",
"Unable to allocate request for default ERP");
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock();
return cqr;
}
erp->cpaddr->cmd_code = CCW_CMD_TIC;
erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr;
erp->function = dasd_default_erp_action;
erp->refers = cqr;
erp->device = device;
erp->magic = cqr->magic;
erp->retries = 16;
erp->status = DASD_CQR_FILLED;
list_add(&erp->list, &device->ccw_queue);
erp->status = DASD_CQR_QUEUED;
return erp;
} /* end dasd_default_erp_action */
/*
* DESCRIPTION
* Frees all ERPs of the current ERP Chain and set the status
* of the original CQR either to DASD_CQR_DONE if ERP was successful
* or to DASD_CQR_FAILED if ERP was NOT successful.
* NOTE: This function is only called if no discipline postaction
* is available
*
* PARAMETER
* erp current erp_head
*
* RETURN VALUES
* cqr pointer to the original CQR
*/
dasd_ccw_req_t *
dasd_default_erp_postaction(dasd_ccw_req_t * cqr)
{
dasd_device_t *device;
int success;
if (cqr->refers == NULL || cqr->function == NULL)
BUG();
device = cqr->device;
success = cqr->status == DASD_CQR_DONE;
/* free all ERPs - but NOT the original cqr */
while (cqr->refers != NULL) {
dasd_ccw_req_t *refers;
refers = cqr->refers;
/* remove the request from the device queue */
list_del(&cqr->list);
/* free the finished erp request */
dasd_free_erp_request(cqr, device);
cqr = refers;
}
/* set corresponding status to original cqr */
if (success)
cqr->status = DASD_CQR_DONE;
else {
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock();
}
return cqr;
} /* end default_erp_postaction */
/*
* Print the hex dump of the memory used by a request. This includes
* all error recovery ccws that have been chained in from of the
* real request.
*/
static inline void
hex_dump_memory(dasd_device_t *device, void *data, int len)
{
int *pint;
pint = (int *) data;
while (len > 0) {
DEV_MESSAGE(KERN_ERR, device, "%p: %08x %08x %08x %08x",
pint, pint[0], pint[1], pint[2], pint[3]);
pint += 4;
len -= 16;
}
}
void
dasd_log_ccw(dasd_ccw_req_t * cqr, int caller, __u32 cpa)
{
dasd_device_t *device;
dasd_ccw_req_t *lcqr;
ccw1_t *ccw;
int cplength;
device = cqr->device;
/* dump sense data */
if (device->discipline && device->discipline->dump_sense)
device->discipline->dump_sense(device, cqr);
/* log the channel program */
for (lcqr = cqr; lcqr != NULL; lcqr = lcqr->refers) {
DEV_MESSAGE(KERN_ERR, device,
"(%s) ERP chain report for req: %p",
caller == 0 ? "EXAMINE" : "ACTION", lcqr);
hex_dump_memory(device, lcqr, sizeof(dasd_ccw_req_t));
cplength = 1;
ccw = lcqr->cpaddr;
while (ccw++->flags & (CCW_FLAG_DC | CCW_FLAG_CC))
cplength++;
if (cplength > 40) { /* log only parts of the CP */
DEV_MESSAGE(KERN_ERR, device, "%s",
"Start of channel program:");
hex_dump_memory(device, lcqr->cpaddr,
40*sizeof(ccw1_t));
DEV_MESSAGE(KERN_ERR, device, "%s",
"End of channel program:");
hex_dump_memory(device, lcqr->cpaddr + cplength - 10,
10*sizeof(ccw1_t));
} else { /* log the whole CP */
DEV_MESSAGE(KERN_ERR, device, "%s",
"Channel program (complete):");
hex_dump_memory(device, lcqr->cpaddr,
cplength*sizeof(ccw1_t));
}
if (lcqr != cqr)
continue;
/*
* Log bytes arround failed CCW but only if we did
* not log the whole CP of the CCW is outside the
* logged CP.
*/
if (cplength > 40 ||
((addr_t) cpa < (addr_t) lcqr->cpaddr &&
(addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) {
DEV_MESSAGE(KERN_ERR, device,
"Failed CCW (%p) (area):",
(void *) (long) cpa);
hex_dump_memory(device, cqr->cpaddr - 10,
20*sizeof(ccw1_t));
}
}
} /* end log_erp_chain */
EXPORT_SYMBOL(dasd_default_erp_action);
EXPORT_SYMBOL(dasd_default_erp_postaction);
EXPORT_SYMBOL(dasd_alloc_erp_request);
EXPORT_SYMBOL(dasd_free_erp_request);
EXPORT_SYMBOL(dasd_log_ccw);
This diff is collapsed.
......@@ -71,6 +71,6 @@ typedef
dasd_fba_characteristics_t;
int dasd_fba_init (void);
void dasd_fba_cleanup (void);
int dasd_fba_init(void);
void dasd_fba_cleanup(void);
#endif /* DASD_FBA_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -158,6 +158,7 @@ MODULE_PARM_DESC(sizes, "list of device (partition) sizes " \
/* The following items are obtained through kmalloc() in init_module() */
Xpram_Dev *xpram_devices = NULL;
int *xpram_hardsects = NULL;
int *xpram_offsets = NULL; /* partition offsets */
#define MIN(x,y) ((x) < (y) ? (x) : (y))
......@@ -938,7 +939,6 @@ int xpram_init(void)
q = BLK_DEFAULT_QUEUE(major);
blk_init_queue (q, xpram_request);
blk_queue_hardsect_size(q, xpram_hardsect);
/* we want to have XPRAM_UNUSED blocks security buffer between devices */
mem_usable=xpram_mem_avail-(XPRAM_UNUSED*(xpram_devs-1));
......@@ -978,6 +978,16 @@ int xpram_init(void)
PRINT_DEBUG(" device(%d) offset = %d kB, size = %d kB\n",i, xpram_offsets[i], xpram_sizes[i]);
#endif
xpram_hardsects = kmalloc(xpram_devs * sizeof(int), GFP_KERNEL);
if (!xpram_hardsects) {
PRINT_ERR("Not enough memory for xpram_hardsects\n");
PRINT_ERR("Giving up xpram\n");
goto fail_malloc_hardsects;
}
for (i=0; i < xpram_devs; i++) /* all the same hardsect */
xpram_hardsects[i] = xpram_hardsect;
hardsect_size[major]=xpram_hardsects;
/*
* allocate the devices -- we can't have them static, as the number
* can be specified at load time
......@@ -1030,6 +1040,7 @@ int xpram_init(void)
goto fail_devfs_register;
}
#endif /* WHY? */
}
return 0; /* succeed */
......@@ -1042,7 +1053,10 @@ int xpram_init(void)
}
kfree(xpram_devices);
kfree (xpram_offsets);
fail_malloc_hardsects:
fail_malloc_devices:
kfree(xpram_hardsects);
hardsect_size[major] = NULL;
fail_malloc:
/* ??? unregister_chrdev(major, "xpram"); */
unregister_blkdev(major, "xpram");
......@@ -1072,6 +1086,7 @@ void cleanup_module(void)
int i;
/* first of all, reset all the data structures */
kfree(hardsect_size[major]);
kfree(xpram_offsets);
blk_clear(major);
......
This diff is collapsed.
......@@ -2,23 +2,28 @@
# S/390 character devices
#
export-objs := hwc_rw.o
export-objs := hwc_rw.o tape.o tape34xx.o
tub3270-objs := tuball.o tubfs.o tubtty.o \
tubttyaid.o tubttybld.o tubttyscl.o \
tubttyrcl.o tubttysiz.o
tape390-$(CONFIG_S390_TAPE_CHAR) += tapechar.o
tape390-$(CONFIG_S390_TAPE_CHAR) += tapechar.o
tape390-$(CONFIG_S390_TAPE_BLOCK) += tapeblock.o
tape390-$(CONFIG_S390_TAPE_3480) += tape3480.o tape34xx.o
tape390-$(CONFIG_S390_TAPE_3490) += tape3490.o tape34xx.o
tape390-objs := tape.o $(sort $(tape390-y))
tape390-objs := tape.o tape34xx.o $(sort $(tape390-y))
tape_3480_mod-objs := tape3480.o
tape_3490_mod-objs := tape3490.o
obj-y += ctrlchar.o
obj-$(CONFIG_TN3215) += con3215.o
obj-$(CONFIG_HWC) += hwc_con.o hwc_rw.o hwc_tty.o
obj-$(CONFIG_HWC_CPI) += hwc_cpi.o
obj-$(CONFIG_TN3270) += tub3270.o
obj-$(CONFIG_S390_TAPE) += tape390.o
obj-$(CONFIG_S390_TAPE) += tape390.o
obj-$(CONFIG_S390_TAPE_3480) += tape_3480_mod.o
obj-$(CONFIG_S390_TAPE_3490) += tape_3490_mod.o
include $(TOPDIR)/Rules.make
......@@ -59,8 +59,6 @@
struct _raw3215_info; /* forward declaration ... */
int raw3215_condevice = -1; /* preset console device */
/*
* Request types for a 3215 device
*/
......@@ -542,7 +540,7 @@ static void raw3215_irq(int irq, void *int_parm, struct pt_regs *regs)
* Has to be called with the s390irq lock held. Can be called
* disabled.
*/
void raw3215_make_room(raw3215_info *raw, unsigned int length)
static void raw3215_make_room(raw3215_info *raw, unsigned int length)
{
while (RAW3215_BUFFER_SIZE - raw->count < length) {
/* there might be a request pending */
......@@ -730,8 +728,11 @@ static void raw3215_shutdown(raw3215_info *raw)
raw->queued_read != NULL) {
raw->flags |= RAW3215_CLOSING;
add_wait_queue(&raw->empty_wait, &wait);
#warning FIXME: use set_current_state instead of current->state=
current->state = TASK_INTERRUPTIBLE;
s390irq_spin_unlock_irqrestore(raw->irq, flags);
/* FIXME: what if schedule is interrupted by a signal,
* shouldn't we loop here? */
schedule();
s390irq_spin_lock_irqsave(raw->irq, flags);
remove_wait_queue(&raw->empty_wait, &wait);
......@@ -752,7 +753,7 @@ raw3215_find_dev(int number)
irq = get_irq_first();
count = 0;
while (count <= number && irq != -ENODEV) {
if (get_dev_info(irq, &dinfo) == -ENODEV)
if (get_dev_info_by_irq(irq, &dinfo) == -ENODEV)
break;
if (dinfo.devno == console_device ||
dinfo.sid_data.cu_type == 0x3215) {
......@@ -794,16 +795,16 @@ con3215_write(struct console *co, const char *str, unsigned int count)
}
}
kdev_t con3215_device(struct console *c)
static kdev_t con3215_device(struct console *c)
{
return MKDEV(TTY_MAJOR, c->index + 64 );
return mk_kdev(TTY_MAJOR, c->index + 64 );
}
/*
* panic() calls console_unblank before the system enters a
* disabled, endless loop.
*/
void con3215_unblank(void)
static void con3215_unblank(void)
{
raw3215_info *raw;
unsigned long flags;
......@@ -843,7 +844,7 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp)
raw3215_info *raw;
int retval, line;
line = MINOR(tty->device) - tty->driver.minor_start;
line = minor(tty->device) - tty->driver.minor_start;
if ((line < 0) || (line >= NR_3215))
return -ENODEV;
......@@ -1057,7 +1058,9 @@ static void tty3215_start(struct tty_struct *tty)
*/
void __init con3215_init(void)
{
#ifdef CONFIG_TN3215_CONSOLE
raw3215_info *raw;
#endif
raw3215_req *req;
int irq;
int i;
......
......@@ -149,6 +149,8 @@ typedef struct {
mto_t;
/* FIXME: don't define static variables in a header!!! */
#warning
static write_hwcb_t write_hwcb_template =
{
sizeof (write_hwcb_t),
......@@ -180,6 +182,7 @@ static write_hwcb_t write_hwcb_template =
}
};
#warning
static mto_t mto_template =
{
sizeof (mto_t),
......@@ -202,6 +205,7 @@ typedef struct {
init_hwcb_t;
#warning
static init_hwcb_t init_hwcb_template =
{
sizeof (init_hwcb_t),
......@@ -258,6 +262,7 @@ typedef struct {
read_hwcb_t;
#warning
static read_hwcb_t read_hwcb_template =
{
PAGE_SIZE,
......
......@@ -34,17 +34,11 @@ void hwc_console_unblank (void);
struct console hwc_console =
{
hwc_console_name,
hwc_console_write,
NULL,
hwc_console_device,
NULL,
hwc_console_unblank,
NULL,
CON_PRINTBUFFER,
0,
0,
NULL
name:hwc_console_name,
write:hwc_console_write,
device:hwc_console_device,
unblank:hwc_console_unblank,
flags:CON_PRINTBUFFER,
};
void
......@@ -54,7 +48,8 @@ hwc_console_write (
unsigned int count)
{
if (console->device (console) != hwc_console.device (&hwc_console)) {
if (kdev_val (console->device (console)) !=
kdev_val (hwc_console.device (&hwc_console))) {
hwc_printk (KERN_WARNING HWC_CON_PRINT_HEADER
"hwc_console_write() called with wrong "
......@@ -67,7 +62,7 @@ hwc_console_write (
kdev_t
hwc_console_device (struct console * c)
{
return MKDEV (hwc_console_major, hwc_console_minor);
return mk_kdev (hwc_console_major, hwc_console_minor);
}
void
......
......@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/sched.h>
#include <asm/semaphore.h>
#include <asm/ebcdic.h>
#include "hwc_rw.h"
......
......@@ -231,6 +231,8 @@ static unsigned long cr0 __attribute__ ((aligned (8)));
static unsigned long cr0_save __attribute__ ((aligned (8)));
static unsigned char psw_mask __attribute__ ((aligned (8)));
static ext_int_info_t ext_int_info_hwc;
#define DELAYED_WRITE 0
#define IMMEDIATE_WRITE 1
......@@ -2004,7 +2006,8 @@ hwc_init (void)
#endif
if (register_external_interrupt (0x2401, hwc_interrupt_handler) != 0)
if (register_early_external_interrupt (0x2401, hwc_interrupt_handler,
&ext_int_info_hwc) != 0)
panic ("Couldn't request external interrupts 0x2401");
spin_lock_init (&hwc_data.lock);
......@@ -2178,6 +2181,7 @@ hwc_do_interrupt (u32 ext_int_param)
unconditional_read_2 (ext_int_param);
break;
default:
break;
}
}
}
......
......@@ -61,7 +61,7 @@ typedef struct {
ioctl_delim_t delim;
} hwc_ioctls_t;
static hwc_ioctls_t _hwc_ioctls;
extern hwc_ioctls_t _hwc_ioctls;
#define HWC_IOCTL_LETTER 'B'
......
......@@ -59,7 +59,7 @@ hwc_tty_open (struct tty_struct *tty,
struct file *filp)
{
if (MINOR (tty->device) - tty->driver.minor_start)
if (minor (tty->device) - tty->driver.minor_start)
return -ENODEV;
tty->driver_data = &hwc_tty_data;
......@@ -78,7 +78,7 @@ static void
hwc_tty_close (struct tty_struct *tty,
struct file *filp)
{
if (MINOR (tty->device) != tty->driver.minor_start) {
if (minor (tty->device) != tty->driver.minor_start) {
printk (KERN_WARNING HWC_TTY_PRINT_HEADER
"do not close hwc tty because of wrong device number");
return;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -19,5 +19,5 @@
typedef struct _tape3480_disc_data_t {
__u8 modeset_byte;
} tape3480_disc_data_t __attribute__ ((packed, aligned(8)));
tape_discipline_t * tape3480_init (int);
tape_discipline_t * tape3480_init (void);
#endif // _TAPE3480_H
This diff is collapsed.
/***************************************************************************
*
* drivers/s390/char/tape3490.h
......@@ -20,5 +19,5 @@
typedef struct _tape3490_disc_data_t {
__u8 modeset_byte;
} tape3490_disc_data_t __attribute__ ((packed, aligned(8)));
tape_discipline_t * tape3490_init (int);
tape_discipline_t * tape3490_init (void);
#endif // _TAPE3490_H
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment