Merge branch 'linus'

Conflicts:

	drivers/scsi/ipr.c

Signed-off-by: James Bottomley <[email protected]>
This commit is contained in:
James Bottomley 2007-02-10 13:45:43 -06:00
commit 81b7bbd193
2025 changed files with 128103 additions and 53737 deletions

View file

@ -103,14 +103,8 @@ config CCW_CONSOLE
depends on TN3215_CONSOLE || TN3270_CONSOLE
default y
config SCLP
bool "Support for SCLP"
help
Include support for the SCLP interface to the service element.
config SCLP_TTY
bool "Support for SCLP line mode terminal"
depends on SCLP
help
Include support for IBM SCLP line-mode terminals.
@ -123,7 +117,6 @@ config SCLP_CONSOLE
config SCLP_VT220_TTY
bool "Support for SCLP VT220-compatible terminal"
depends on SCLP
help
Include support for an IBM SCLP VT220-compatible terminal.
@ -136,7 +129,6 @@ config SCLP_VT220_CONSOLE
config SCLP_CPI
tristate "Control-Program Identification"
depends on SCLP
help
This option enables the hardware console interface for system
identification. This is commonly used for workload management and

View file

@ -2,6 +2,8 @@
# Makefile for the S/390 specific device drivers
#
CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
obj-y += s390mach.o sysinfo.o s390_rdev.o
obj-y += cio/ block/ char/ crypto/ net/ scsi/

View file

@ -37,6 +37,7 @@
*/
debug_info_t *dasd_debug_area;
struct dasd_discipline *dasd_diag_discipline_pointer;
void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
MODULE_AUTHOR("Holger Smolinski <[email protected]>");
MODULE_DESCRIPTION("Linux on S/390 DASD device driver,"
@ -51,7 +52,6 @@ static int dasd_alloc_queue(struct dasd_device * device);
static void dasd_setup_queue(struct dasd_device * device);
static void dasd_free_queue(struct dasd_device * device);
static void dasd_flush_request_queue(struct dasd_device *);
static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
static int dasd_flush_ccw_queue(struct dasd_device *, int);
static void dasd_tasklet(struct dasd_device *);
static void do_kick_device(struct work_struct *);
@ -483,7 +483,7 @@ unsigned int dasd_profile_level = DASD_PROFILE_OFF;
/*
* Add profiling information for cqr before execution.
*/
static inline void
static void
dasd_profile_start(struct dasd_device *device, struct dasd_ccw_req * cqr,
struct request *req)
{
@ -505,7 +505,7 @@ dasd_profile_start(struct dasd_device *device, struct dasd_ccw_req * cqr,
/*
* Add profiling information for cqr after execution.
*/
static inline void
static void
dasd_profile_end(struct dasd_device *device, struct dasd_ccw_req * cqr,
struct request *req)
{
@ -1022,8 +1022,6 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
irb->scsw.cstat == 0 &&
!irb->esw.esw0.erw.cons)
era = dasd_era_none;
else if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags))
era = dasd_era_fatal; /* don't recover this request */
else if (irb->esw.esw0.erw.cons)
era = device->discipline->examine_error(cqr, irb);
else
@ -1104,7 +1102,7 @@ __dasd_process_erp(struct dasd_device *device, struct dasd_ccw_req *cqr)
/*
* Process ccw request queue.
*/
static inline void
static void
__dasd_process_ccw_queue(struct dasd_device * device,
struct list_head *final_queue)
{
@ -1127,7 +1125,9 @@ restart:
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock();
} else {
if (cqr->irb.esw.esw0.erw.cons) {
if (cqr->irb.esw.esw0.erw.cons &&
test_bit(DASD_CQR_FLAGS_USE_ERP,
&cqr->flags)) {
erp_fn = device->discipline->
erp_action(cqr);
erp_fn(cqr);
@ -1181,7 +1181,7 @@ dasd_end_request_cb(struct dasd_ccw_req * cqr, void *data)
/*
* Fetch requests from the block device queue.
*/
static inline void
static void
__dasd_process_blk_queue(struct dasd_device * device)
{
request_queue_t *queue;
@ -1232,6 +1232,19 @@ __dasd_process_blk_queue(struct dasd_device * device)
if (IS_ERR(cqr)) {
if (PTR_ERR(cqr) == -ENOMEM)
break; /* terminate request queue loop */
if (PTR_ERR(cqr) == -EAGAIN) {
/*
* The current request cannot be build right
* now, we have to try later. If this request
* is the head-of-queue we stop the device
* for 1/2 second.
*/
if (!list_empty(&device->ccw_queue))
break;
device->stopped |= DASD_STOPPED_PENDING;
dasd_set_timer(device, HZ/2);
break;
}
DBF_DEV_EVENT(DBF_ERR, device,
"CCW creation failed (rc=%ld) "
"on request %p",
@ -1254,7 +1267,7 @@ __dasd_process_blk_queue(struct dasd_device * device)
* Take a look at the first request on the ccw queue and check
* if it reached its expire time. If so, terminate the IO.
*/
static inline void
static void
__dasd_check_expire(struct dasd_device * device)
{
struct dasd_ccw_req *cqr;
@ -1285,7 +1298,7 @@ __dasd_check_expire(struct dasd_device * device)
* Take a look at the first request on the ccw queue and check
* if it needs to be started.
*/
static inline void
static void
__dasd_start_head(struct dasd_device * device)
{
struct dasd_ccw_req *cqr;

View file

@ -170,7 +170,6 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
/* log the erp chain if fatal error occurred */
if ((era == dasd_era_fatal) && (device->state >= DASD_STATE_READY)) {
dasd_log_sense(cqr, irb);
dasd_log_ccw(cqr, 0, irb->scsw.cpa);
}
return era;
@ -2640,7 +2639,6 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
struct dasd_ccw_req *erp = NULL;
struct dasd_device *device = cqr->device;
__u32 cpa = cqr->irb.scsw.cpa;
struct dasd_ccw_req *temp_erp = NULL;
if (device->features & DASD_FEATURE_ERPLOG) {
@ -2706,9 +2704,6 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
}
}
if (erp->status == DASD_CQR_FAILED)
dasd_log_ccw(erp, 1, cpa);
/* enqueue added ERP request */
if (erp->status == DASD_CQR_FILLED) {
erp->status = DASD_CQR_QUEUED;

View file

@ -136,7 +136,7 @@ __setup ("dasd=", dasd_call_setup);
/*
* Read a device busid/devno from a string.
*/
static inline int
static int
dasd_busid(char **str, int *id0, int *id1, int *devno)
{
int val, old_style;
@ -182,7 +182,7 @@ dasd_busid(char **str, int *id0, int *id1, int *devno)
* only one: "ro" for read-only devices. The default feature set
* is empty (value 0).
*/
static inline int
static int
dasd_feature_list(char *str, char **endp)
{
int features, len, rc;
@ -341,7 +341,7 @@ dasd_parse_range( char *parsestring ) {
return ERR_PTR(-EINVAL);
}
static inline char *
static char *
dasd_parse_next_element( char *parsestring ) {
char * residual_str;
residual_str = dasd_parse_keyword(parsestring);

View file

@ -43,7 +43,7 @@ MODULE_LICENSE("GPL");
#define DIAG_MAX_RETRIES 32
#define DIAG_TIMEOUT 50 * HZ
struct dasd_discipline dasd_diag_discipline;
static struct dasd_discipline dasd_diag_discipline;
struct dasd_diag_private {
struct dasd_diag_characteristics rdc_data;
@ -90,7 +90,7 @@ static inline int dia250(void *iob, int cmd)
* block offset. On success, return zero and set end_block to contain the
* number of blocks on the device minus the specified offset. Return non-zero
* otherwise. */
static __inline__ int
static inline int
mdsk_init_io(struct dasd_device *device, unsigned int blocksize,
blocknum_t offset, blocknum_t *end_block)
{
@ -117,7 +117,7 @@ mdsk_init_io(struct dasd_device *device, unsigned int blocksize,
/* Remove block I/O environment for device. Return zero on success, non-zero
* otherwise. */
static __inline__ int
static inline int
mdsk_term_io(struct dasd_device * device)
{
struct dasd_diag_private *private;
@ -576,7 +576,7 @@ dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
"dump sense not available for DIAG data");
}
struct dasd_discipline dasd_diag_discipline = {
static struct dasd_discipline dasd_diag_discipline = {
.owner = THIS_MODULE,
.name = "DIAG",
.ebcname = "DIAG",

View file

@ -134,44 +134,7 @@ ceil_quot(unsigned int d1, unsigned int d2)
return (d1 + (d2 - 1)) / d2;
}
static inline int
bytes_per_record(struct dasd_eckd_characteristics *rdc, int kl, int dl)
{
unsigned int fl1, fl2, int1, int2;
int bpr;
switch (rdc->formula) {
case 0x01:
fl1 = round_up_multiple(ECKD_F2(rdc) + dl, ECKD_F1(rdc));
fl2 = round_up_multiple(kl ? ECKD_F2(rdc) + kl : 0,
ECKD_F1(rdc));
bpr = fl1 + fl2;
break;
case 0x02:
int1 = ceil_quot(dl + ECKD_F6(rdc), ECKD_F5(rdc) << 1);
int2 = ceil_quot(kl + ECKD_F6(rdc), ECKD_F5(rdc) << 1);
fl1 = round_up_multiple(ECKD_F1(rdc) * ECKD_F2(rdc) + dl +
ECKD_F6(rdc) + ECKD_F4(rdc) * int1,
ECKD_F1(rdc));
fl2 = round_up_multiple(ECKD_F1(rdc) * ECKD_F3(rdc) + kl +
ECKD_F6(rdc) + ECKD_F4(rdc) * int2,
ECKD_F1(rdc));
bpr = fl1 + fl2;
break;
default:
bpr = 0;
break;
}
return bpr;
}
static inline unsigned int
bytes_per_track(struct dasd_eckd_characteristics *rdc)
{
return *(unsigned int *) (rdc->byte_per_track) >> 8;
}
static inline unsigned int
static unsigned int
recs_per_track(struct dasd_eckd_characteristics * rdc,
unsigned int kl, unsigned int dl)
{
@ -204,37 +167,39 @@ recs_per_track(struct dasd_eckd_characteristics * rdc,
return 0;
}
static inline void
static int
check_XRC (struct ccw1 *de_ccw,
struct DE_eckd_data *data,
struct dasd_device *device)
{
struct dasd_eckd_private *private;
int rc;
private = (struct dasd_eckd_private *) device->private;
if (!private->rdc_data.facilities.XRC_supported)
return 0;
/* switch on System Time Stamp - needed for XRC Support */
if (private->rdc_data.facilities.XRC_supported) {
data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */
data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */
data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
rc = get_sync_clock(&data->ep_sys_time);
/* Ignore return code if sync clock is switched off. */
if (rc == -ENOSYS || rc == -EACCES)
rc = 0;
data->ep_sys_time = get_clock ();
de_ccw->count = sizeof (struct DE_eckd_data);
de_ccw->flags |= CCW_FLAG_SLI;
return rc;
}
de_ccw->count = sizeof (struct DE_eckd_data);
de_ccw->flags |= CCW_FLAG_SLI;
}
return;
} /* end check_XRC */
static inline void
static int
define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
int totrk, int cmd, struct dasd_device * device)
{
struct dasd_eckd_private *private;
struct ch_t geo, beg, end;
int rc = 0;
private = (struct dasd_eckd_private *) device->private;
@ -263,12 +228,12 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
case DASD_ECKD_CCW_WRITE_KD_MT:
data->mask.perm = 0x02;
data->attributes.operation = private->attrib.operation;
check_XRC (ccw, data, device);
rc = check_XRC (ccw, data, device);
break;
case DASD_ECKD_CCW_WRITE_CKD:
case DASD_ECKD_CCW_WRITE_CKD_MT:
data->attributes.operation = DASD_BYPASS_CACHE;
check_XRC (ccw, data, device);
rc = check_XRC (ccw, data, device);
break;
case DASD_ECKD_CCW_ERASE:
case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
@ -276,7 +241,7 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
data->mask.perm = 0x3;
data->mask.auth = 0x1;
data->attributes.operation = DASD_BYPASS_CACHE;
check_XRC (ccw, data, device);
rc = check_XRC (ccw, data, device);
break;
default:
DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
@ -312,9 +277,10 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
data->beg_ext.head = beg.head;
data->end_ext.cyl = end.cyl;
data->end_ext.head = end.head;
return rc;
}
static inline void
static void
locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
int rec_on_trk, int no_rec, int cmd,
struct dasd_device * device, int reclen)
@ -548,7 +514,7 @@ dasd_eckd_read_conf(struct dasd_device *device)
/*
* Build CP for Perform Subsystem Function - SSC.
*/
struct dasd_ccw_req *
static struct dasd_ccw_req *
dasd_eckd_build_psf_ssc(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
@ -1200,7 +1166,12 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
return cqr;
ccw = cqr->cpaddr;
/* First ccw is define extent. */
define_extent(ccw++, cqr->data, first_trk, last_trk, cmd, device);
if (define_extent(ccw++, cqr->data, first_trk,
last_trk, cmd, device) == -EAGAIN) {
/* Clock not in sync and XRC is enabled. Try again later. */
dasd_sfree_request(cqr, device);
return ERR_PTR(-EAGAIN);
}
/* Build locate_record+read/write/ccws. */
idaws = (unsigned long *) (cqr->data + sizeof(struct DE_eckd_data));
LO_data = (struct LO_eckd_data *) (idaws + cidaw);
@ -1380,7 +1351,7 @@ dasd_eckd_release(struct dasd_device *device)
cqr->device = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->retries = 0;
cqr->retries = 2; /* set retry counter to enable basic ERP */
cqr->expires = 2 * HZ;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
@ -1420,7 +1391,7 @@ dasd_eckd_reserve(struct dasd_device *device)
cqr->device = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->retries = 0;
cqr->retries = 2; /* set retry counter to enable basic ERP */
cqr->expires = 2 * HZ;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
@ -1459,7 +1430,7 @@ dasd_eckd_steal_lock(struct dasd_device *device)
cqr->device = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->retries = 0;
cqr->retries = 2; /* set retry counter to enable basic ERP */
cqr->expires = 2 * HZ;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
@ -1609,7 +1580,7 @@ dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp)
* Dump the range of CCWs into 'page' buffer
* and return number of printed chars.
*/
static inline int
static int
dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
{
int len, count;

View file

@ -658,18 +658,24 @@ static struct file_operations dasd_eer_fops = {
.owner = THIS_MODULE,
};
static struct miscdevice dasd_eer_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "dasd_eer",
.fops = &dasd_eer_fops,
};
static struct miscdevice *dasd_eer_dev = NULL;
int __init dasd_eer_init(void)
{
int rc;
rc = misc_register(&dasd_eer_dev);
dasd_eer_dev = kzalloc(sizeof(*dasd_eer_dev), GFP_KERNEL);
if (!dasd_eer_dev)
return -ENOMEM;
dasd_eer_dev->minor = MISC_DYNAMIC_MINOR;
dasd_eer_dev->name = "dasd_eer";
dasd_eer_dev->fops = &dasd_eer_fops;
rc = misc_register(dasd_eer_dev);
if (rc) {
kfree(dasd_eer_dev);
dasd_eer_dev = NULL;
MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
"register misc device");
return rc;
@ -680,5 +686,9 @@ int __init dasd_eer_init(void)
void dasd_eer_exit(void)
{
WARN_ON(misc_deregister(&dasd_eer_dev) != 0);
if (dasd_eer_dev) {
WARN_ON(misc_deregister(dasd_eer_dev) != 0);
kfree(dasd_eer_dev);
dasd_eer_dev = NULL;
}
}

View file

@ -152,25 +152,6 @@ dasd_default_erp_postaction(struct dasd_ccw_req * 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(struct dasd_device *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_sense(struct dasd_ccw_req *cqr, struct irb *irb)
{
@ -182,69 +163,8 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb)
device->discipline->dump_sense(device, cqr, irb);
}
void
dasd_log_ccw(struct dasd_ccw_req * cqr, int caller, __u32 cpa)
{
struct dasd_device *device;
struct dasd_ccw_req *lcqr;
struct ccw1 *ccw;
int cplength;
device = cqr->device;
/* 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(struct dasd_ccw_req));
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(struct ccw1));
DEV_MESSAGE(KERN_ERR, device, "%s",
"End of channel program:");
hex_dump_memory(device, lcqr->cpaddr + cplength - 10,
10*sizeof(struct ccw1));
} else { /* log the whole CP */
DEV_MESSAGE(KERN_ERR, device, "%s",
"Channel program (complete):");
hex_dump_memory(device, lcqr->cpaddr,
cplength*sizeof(struct ccw1));
}
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(struct ccw1));
}
}
} /* 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_sense);
EXPORT_SYMBOL(dasd_log_ccw);

View file

@ -75,7 +75,7 @@ static struct ccw_driver dasd_fba_driver = {
.notify = dasd_generic_notify,
};
static inline void
static void
define_extent(struct ccw1 * ccw, struct DE_fba_data *data, int rw,
int blksize, int beg, int nr)
{
@ -95,7 +95,7 @@ define_extent(struct ccw1 * ccw, struct DE_fba_data *data, int rw,
data->ext_end = nr - 1;
}
static inline void
static void
locate_record(struct ccw1 * ccw, struct LO_fba_data *data, int rw,
int block_nr, int block_ct)
{

View file

@ -147,7 +147,7 @@ dasd_destroy_partitions(struct dasd_device * device)
*/
memset(&bpart, 0, sizeof(struct blkpg_partition));
memset(&barg, 0, sizeof(struct blkpg_ioctl_arg));
barg.data = (void __user *) &bpart;
barg.data = (void __force __user *) &bpart;
barg.op = BLKPG_DEL_PARTITION;
for (bpart.pno = device->gdp->minors - 1; bpart.pno > 0; bpart.pno--)
ioctl_by_bdev(bdev, BLKPG, (unsigned long) &barg);

View file

@ -559,7 +559,6 @@ struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int,
struct dasd_device *);
void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
void dasd_log_ccw(struct dasd_ccw_req *, int, __u32);
/* externals in dasd_3370_erp.c */
dasd_era_t dasd_3370_erp_examine(struct dasd_ccw_req *, struct irb *);

View file

@ -28,7 +28,7 @@ static struct proc_dir_entry *dasd_proc_root_entry = NULL;
static struct proc_dir_entry *dasd_devices_entry = NULL;
static struct proc_dir_entry *dasd_statistics_entry = NULL;
static inline char *
static char *
dasd_get_user_string(const char __user *user_buf, size_t user_len)
{
char *buffer;
@ -154,7 +154,7 @@ static struct file_operations dasd_devices_file_ops = {
.release = seq_release,
};
static inline int
static int
dasd_calc_metrics(char *page, char **start, off_t off,
int count, int *eof, int len)
{
@ -167,8 +167,8 @@ dasd_calc_metrics(char *page, char **start, off_t off,
return len;
}
static inline char *
dasd_statistics_array(char *str, int *array, int shift)
static char *
dasd_statistics_array(char *str, unsigned int *array, int shift)
{
int i;

View file

@ -102,7 +102,7 @@ dcssblk_release_segment(struct device *dev)
* device needs to be enqueued before the semaphore is
* freed.
*/
static inline int
static int
dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info)
{
int minor, found;
@ -230,7 +230,7 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch
SEGMENT_SHARED);
if (rc < 0) {
BUG_ON(rc == -EINVAL);
if (rc == -EIO || rc == -ENOENT)
if (rc != -EAGAIN)
goto removeseg;
} else {
dev_info->is_shared = 1;
@ -253,7 +253,7 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch
SEGMENT_EXCLUSIVE);
if (rc < 0) {
BUG_ON(rc == -EINVAL);
if (rc == -EIO || rc == -ENOENT)
if (rc != -EAGAIN)
goto removeseg;
} else {
dev_info->is_shared = 0;

View file

@ -2,7 +2,8 @@
# S/390 character devices
#
obj-y += ctrlchar.o keyboard.o defkeymap.o
obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \
sclp_info.o
obj-$(CONFIG_TN3270) += raw3270.o
obj-$(CONFIG_TN3270_CONSOLE) += con3270.o
@ -11,7 +12,6 @@ obj-$(CONFIG_TN3270_FS) += fs3270.o
obj-$(CONFIG_TN3215) += con3215.o
obj-$(CONFIG_SCLP) += sclp.o sclp_rw.o sclp_quiesce.o
obj-$(CONFIG_SCLP_TTY) += sclp_tty.o
obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o
obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o

View file

@ -1121,7 +1121,7 @@ static const struct tty_operations tty3215_ops = {
* 3215 tty registration code called from tty_init().
* Most kernel services (incl. kmalloc) are available at this poimt.
*/
int __init
static int __init
tty3215_init(void)
{
struct tty_driver *driver;

View file

@ -69,8 +69,7 @@ static void con3270_update(struct con3270 *);
/*
* Setup timeout for a device. On timeout trigger an update.
*/
void
con3270_set_timer(struct con3270 *cp, int expires)
static void con3270_set_timer(struct con3270 *cp, int expires)
{
if (expires == 0) {
if (timer_pending(&cp->timer))

View file

@ -5,6 +5,8 @@
#include <linux/types.h>
#include <linux/keyboard.h>
#include <linux/kd.h>
#include <linux/kbd_kern.h>
#include <linux/kbd_diacr.h>
u_short plain_map[NR_KEYS] = {
0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000,

View file

@ -23,7 +23,7 @@
#include "raw3270.h"
#include "ctrlchar.h"
struct raw3270_fn fs3270_fn;
static struct raw3270_fn fs3270_fn;
struct fs3270 {
struct raw3270_view view;
@ -401,7 +401,7 @@ fs3270_release(struct raw3270_view *view)
}
/* View to a 3270 device. Can be console, tty or fullscreen. */
struct raw3270_fn fs3270_fn = {
static struct raw3270_fn fs3270_fn = {
.activate = fs3270_activate,
.deactivate = fs3270_deactivate,
.intv = (void *) fs3270_irq,

View file

@ -148,6 +148,7 @@ kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc)
}
}
#if 0
/*
* Generate ebcdic -> ascii translation table from kbd_data.
*/
@ -173,6 +174,7 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc)
}
}
}
#endif
/*
* We have a combining character DIACR here, followed by the character CH.

View file

@ -3,7 +3,7 @@
*
* Character device driver for reading z/VM *MONITOR service records.
*
* Copyright (C) 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH.
* Copyright 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH.
*
* Author: Gerald Schaefer <geraldsc@de.ibm.com>
*/
@ -22,7 +22,7 @@
#include <asm/ebcdic.h>
#include <asm/extmem.h>
#include <linux/poll.h>
#include "../net/iucv.h"
#include <net/iucv/iucv.h>
//#define MON_DEBUG /* Debug messages on/off */
@ -50,14 +50,13 @@ static char mon_dcss_name[9] = "MONDCSS\0";
struct mon_msg {
u32 pos;
u32 mca_offset;
iucv_MessagePending local_eib;
struct iucv_message msg;
char msglim_reached;
char replied_msglim;
};
struct mon_private {
u16 pathid;
iucv_handle_t iucv_handle;
struct iucv_path *path;
struct mon_msg *msg_array[MON_MSGLIM];
unsigned int write_index;
unsigned int read_index;
@ -75,8 +74,6 @@ static unsigned long mon_dcss_end;
static DECLARE_WAIT_QUEUE_HEAD(mon_read_wait_queue);
static DECLARE_WAIT_QUEUE_HEAD(mon_conn_wait_queue);
static u8 iucv_host[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static u8 user_data_connect[16] = {
/* Version code, must be 0x01 for shared mode */
0x01,
@ -100,8 +97,7 @@ static u8 user_data_sever[16] = {
* Create the 8 bytes EBCDIC DCSS segment name from
* an ASCII name, incl. padding
*/
static inline void
dcss_mkname(char *ascii_name, char *ebcdic_name)
static inline void dcss_mkname(char *ascii_name, char *ebcdic_name)
{
int i;
@ -119,8 +115,7 @@ dcss_mkname(char *ascii_name, char *ebcdic_name)
* print appropriate error message for segment_load()/segment_type()
* return code
*/
static void
mon_segment_warn(int rc, char* seg_name)
static void mon_segment_warn(int rc, char* seg_name)
{
switch (rc) {
case -ENOENT:
@ -166,44 +161,37 @@ mon_segment_warn(int rc, char* seg_name)
}
}
static inline unsigned long
mon_mca_start(struct mon_msg *monmsg)
static inline unsigned long mon_mca_start(struct mon_msg *monmsg)
{
return monmsg->local_eib.ln1msg1.iprmmsg1_u32;
return *(u32 *) &monmsg->msg.rmmsg;
}
static inline unsigned long
mon_mca_end(struct mon_msg *monmsg)
static inline unsigned long mon_mca_end(struct mon_msg *monmsg)
{
return monmsg->local_eib.ln1msg2.ipbfln1f;
return *(u32 *) &monmsg->msg.rmmsg[4];
}
static inline u8
mon_mca_type(struct mon_msg *monmsg, u8 index)
static inline u8 mon_mca_type(struct mon_msg *monmsg, u8 index)
{
return *((u8 *) mon_mca_start(monmsg) + monmsg->mca_offset + index);
}
static inline u32
mon_mca_size(struct mon_msg *monmsg)
static inline u32 mon_mca_size(struct mon_msg *monmsg)
{
return mon_mca_end(monmsg) - mon_mca_start(monmsg) + 1;
}
static inline u32
mon_rec_start(struct mon_msg *monmsg)
static inline u32 mon_rec_start(struct mon_msg *monmsg)
{
return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 4));
}
static inline u32
mon_rec_end(struct mon_msg *monmsg)
static inline u32 mon_rec_end(struct mon_msg *monmsg)
{
return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 8));
}
static inline int
mon_check_mca(struct mon_msg *monmsg)
static inline int mon_check_mca(struct mon_msg *monmsg)
{
if ((mon_rec_end(monmsg) <= mon_rec_start(monmsg)) ||
(mon_rec_start(monmsg) < mon_dcss_start) ||
@ -221,20 +209,17 @@ mon_check_mca(struct mon_msg *monmsg)
return 0;
}
static inline int
mon_send_reply(struct mon_msg *monmsg, struct mon_private *monpriv)
static inline int mon_send_reply(struct mon_msg *monmsg,
struct mon_private *monpriv)
{
u8 prmmsg[8];
int rc;
P_DEBUG("read, REPLY: pathid = 0x%04X, msgid = 0x%08X, trgcls = "
"0x%08X\n\n",
monmsg->local_eib.ippathid, monmsg->local_eib.ipmsgid,
monmsg->local_eib.iptrgcls);
rc = iucv_reply_prmmsg(monmsg->local_eib.ippathid,
monmsg->local_eib.ipmsgid,
monmsg->local_eib.iptrgcls,
0, prmmsg);
monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class);
rc = iucv_message_reply(monpriv->path, &monmsg->msg,
IUCV_IPRMDATA, NULL, 0);
atomic_dec(&monpriv->msglim_count);
if (likely(!monmsg->msglim_reached)) {
monmsg->pos = 0;
@ -251,10 +236,19 @@ mon_send_reply(struct mon_msg *monmsg, struct mon_private *monpriv)
return 0;
}
static inline struct mon_private *
mon_alloc_mem(void)
static inline void mon_free_mem(struct mon_private *monpriv)
{
int i,j;
int i;
for (i = 0; i < MON_MSGLIM; i++)
if (monpriv->msg_array[i])
kfree(monpriv->msg_array[i]);
kfree(monpriv);
}
static inline struct mon_private *mon_alloc_mem(void)
{
int i;
struct mon_private *monpriv;
monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL);
@ -267,16 +261,15 @@ mon_alloc_mem(void)
GFP_KERNEL);
if (!monpriv->msg_array[i]) {
P_ERROR("open, no memory for msg_array\n");
for (j = 0; j < i; j++)
kfree(monpriv->msg_array[j]);
mon_free_mem(monpriv);
return NULL;
}
}
return monpriv;
}
static inline void
mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv)
static inline void mon_read_debug(struct mon_msg *monmsg,
struct mon_private *monpriv)
{
#ifdef MON_DEBUG
u8 msg_type[2], mca_type;
@ -284,7 +277,7 @@ mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv)
records_len = mon_rec_end(monmsg) - mon_rec_start(monmsg) + 1;
memcpy(msg_type, &monmsg->local_eib.iptrgcls, 2);
memcpy(msg_type, &monmsg->msg.class, 2);
EBCASC(msg_type, 2);
mca_type = mon_mca_type(monmsg, 0);
EBCASC(&mca_type, 1);
@ -292,8 +285,7 @@ mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv)
P_DEBUG("read, mon_read_index = %i, mon_write_index = %i\n",
monpriv->read_index, monpriv->write_index);
P_DEBUG("read, pathid = 0x%04X, msgid = 0x%08X, trgcls = 0x%08X\n",
monmsg->local_eib.ippathid, monmsg->local_eib.ipmsgid,
monmsg->local_eib.iptrgcls);
monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class);
P_DEBUG("read, msg_type = '%c%c', mca_type = '%c' / 0x%X / 0x%X\n",
msg_type[0], msg_type[1], mca_type ? mca_type : 'X',
mon_mca_type(monmsg, 1), mon_mca_type(monmsg, 2));
@ -306,8 +298,7 @@ mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv)
#endif
}
static inline void
mon_next_mca(struct mon_msg *monmsg)
static inline void mon_next_mca(struct mon_msg *monmsg)
{
if (likely((mon_mca_size(monmsg) - monmsg->mca_offset) == 12))
return;
@ -316,8 +307,7 @@ mon_next_mca(struct mon_msg *monmsg)
monmsg->pos = 0;
}
static inline struct mon_msg *
mon_next_message(struct mon_private *monpriv)
static inline struct mon_msg *mon_next_message(struct mon_private *monpriv)
{
struct mon_msg *monmsg;
@ -342,39 +332,37 @@ mon_next_message(struct mon_private *monpriv)
/******************************************************************************
* IUCV handler *
*****************************************************************************/
static void
mon_iucv_ConnectionComplete(iucv_ConnectionComplete *eib, void *pgm_data)
static void mon_iucv_path_complete(struct iucv_path *path, u8 ipuser[16])
{
struct mon_private *monpriv = (struct mon_private *) pgm_data;
struct mon_private *monpriv = path->private;
P_DEBUG("IUCV connection completed\n");
P_DEBUG("IUCV ACCEPT (from *MONITOR): Version = 0x%02X, Event = "
"0x%02X, Sample = 0x%02X\n",
eib->ipuser[0], eib->ipuser[1], eib->ipuser[2]);
ipuser[0], ipuser[1], ipuser[2]);
atomic_set(&monpriv->iucv_connected, 1);
wake_up(&mon_conn_wait_queue);
}
static void
mon_iucv_ConnectionSevered(iucv_ConnectionSevered *eib, void *pgm_data)
static void mon_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
{
struct mon_private *monpriv = (struct mon_private *) pgm_data;
struct mon_private *monpriv = path->private;
P_ERROR("IUCV connection severed with rc = 0x%X\n",
(u8) eib->ipuser[0]);
P_ERROR("IUCV connection severed with rc = 0x%X\n", ipuser[0]);
iucv_path_sever(path, NULL);
atomic_set(&monpriv->iucv_severed, 1);
wake_up(&mon_conn_wait_queue);
wake_up_interruptible(&mon_read_wait_queue);
}
static void
mon_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data)
static void mon_iucv_message_pending(struct iucv_path *path,
struct iucv_message *msg)
{
struct mon_private *monpriv = (struct mon_private *) pgm_data;
struct mon_private *monpriv = path->private;
P_DEBUG("IUCV message pending\n");
memcpy(&monpriv->msg_array[monpriv->write_index]->local_eib, eib,
sizeof(iucv_MessagePending));
memcpy(&monpriv->msg_array[monpriv->write_index]->msg,
msg, sizeof(*msg));
if (atomic_inc_return(&monpriv->msglim_count) == MON_MSGLIM) {
P_WARNING("IUCV message pending, message limit (%i) reached\n",
MON_MSGLIM);
@ -385,54 +373,45 @@ mon_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data)
wake_up_interruptible(&mon_read_wait_queue);
}
static iucv_interrupt_ops_t mon_iucvops = {
.ConnectionComplete = mon_iucv_ConnectionComplete,
.ConnectionSevered = mon_iucv_ConnectionSevered,
.MessagePending = mon_iucv_MessagePending,
static struct iucv_handler monreader_iucv_handler = {
.path_complete = mon_iucv_path_complete,
.path_severed = mon_iucv_path_severed,
.message_pending = mon_iucv_message_pending,
};
/******************************************************************************
* file operations *
*****************************************************************************/
static int
mon_open(struct inode *inode, struct file *filp)
static int mon_open(struct inode *inode, struct file *filp)
{
int rc, i;
struct mon_private *monpriv;
int rc;
/*
* only one user allowed
*/
rc = -EBUSY;
if (test_and_set_bit(MON_IN_USE, &mon_in_use))
return -EBUSY;
goto out;
rc = -ENOMEM;
monpriv = mon_alloc_mem();
if (!monpriv)
return -ENOMEM;
goto out_use;
/*
* Register with IUCV and connect to *MONITOR service
* Connect to *MONITOR service
*/
monpriv->iucv_handle = iucv_register_program("my_monreader ",
MON_SERVICE,
NULL,
&mon_iucvops,
monpriv);
if (!monpriv->iucv_handle) {
P_ERROR("failed to register with iucv driver\n");
rc = -EIO;
goto out_error;
}
P_INFO("open, registered with IUCV\n");
rc = iucv_connect(&monpriv->pathid, MON_MSGLIM, user_data_connect,
MON_SERVICE, iucv_host, IPRMDATA, NULL, NULL,
monpriv->iucv_handle, NULL);
monpriv->path = iucv_path_alloc(MON_MSGLIM, IUCV_IPRMDATA, GFP_KERNEL);
if (!monpriv->path)
goto out_priv;
rc = iucv_path_connect(monpriv->path, &monreader_iucv_handler,
MON_SERVICE, NULL, user_data_connect, monpriv);
if (rc) {
P_ERROR("iucv connection to *MONITOR failed with "
"IPUSER SEVER code = %i\n", rc);
rc = -EIO;
goto out_unregister;
goto out_path;
}
/*
* Wait for connection confirmation
@ -444,24 +423,23 @@ mon_open(struct inode *inode, struct file *filp)
atomic_set(&monpriv->iucv_severed, 0);
atomic_set(&monpriv->iucv_connected, 0);
rc = -EIO;
goto out_unregister;
goto out_path;
}
P_INFO("open, established connection to *MONITOR service\n\n");
filp->private_data = monpriv;
return nonseekable_open(inode, filp);
out_unregister:
iucv_unregister_program(monpriv->iucv_handle);
out_error:
for (i = 0; i < MON_MSGLIM; i++)
kfree(monpriv->msg_array[i]);
kfree(monpriv);
out_path:
kfree(monpriv->path);
out_priv:
mon_free_mem(monpriv);
out_use:
clear_bit(MON_IN_USE, &mon_in_use);
out:
return rc;
}
static int
mon_close(struct inode *inode, struct file *filp)
static int mon_close(struct inode *inode, struct file *filp)
{
int rc, i;
struct mon_private *monpriv = filp->private_data;
@ -469,18 +447,12 @@ mon_close(struct inode *inode, struct file *filp)
/*
* Close IUCV connection and unregister
*/
rc = iucv_sever(monpriv->pathid, user_data_sever);
rc = iucv_path_sever(monpriv->path, user_data_sever);
if (rc)
P_ERROR("close, iucv_sever failed with rc = %i\n", rc);
else
P_INFO("close, terminated connection to *MONITOR service\n");
rc = iucv_unregister_program(monpriv->iucv_handle);
if (rc)
P_ERROR("close, iucv_unregister failed with rc = %i\n", rc);
else
P_INFO("close, unregistered with IUCV\n");
atomic_set(&monpriv->iucv_severed, 0);
atomic_set(&monpriv->iucv_connected, 0);
atomic_set(&monpriv->read_ready, 0);
@ -495,8 +467,8 @@ mon_close(struct inode *inode, struct file *filp)
return 0;
}
static ssize_t
mon_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
static ssize_t mon_read(struct file *filp, char __user *data,
size_t count, loff_t *ppos)
{
struct mon_private *monpriv = filp->private_data;
struct mon_msg *monmsg;
@ -563,8 +535,7 @@ out_copy:
return count;
}
static unsigned int
mon_poll(struct file *filp, struct poll_table_struct *p)
static unsigned int mon_poll(struct file *filp, struct poll_table_struct *p)
{
struct mon_private *monpriv = filp->private_data;
@ -593,8 +564,7 @@ static struct miscdevice mon_dev = {
/******************************************************************************
* module init/exit *
*****************************************************************************/
static int __init
mon_init(void)
static int __init mon_init(void)
{
int rc;
@ -603,22 +573,34 @@ mon_init(void)
return -ENODEV;
}
/*
* Register with IUCV and connect to *MONITOR service
*/
rc = iucv_register(&monreader_iucv_handler, 1);
if (rc) {
P_ERROR("failed to register with iucv driver\n");
return rc;
}
P_INFO("open, registered with IUCV\n");
rc = segment_type(mon_dcss_name);
if (rc < 0) {
mon_segment_warn(rc, mon_dcss_name);
return rc;
goto out_iucv;
}
if (rc != SEG_TYPE_SC) {
P_ERROR("segment %s has unsupported type, should be SC\n",
mon_dcss_name);
return -EINVAL;
rc = -EINVAL;
goto out_iucv;
}
rc = segment_load(mon_dcss_name, SEGMENT_SHARED,
&mon_dcss_start, &mon_dcss_end);
if (rc < 0) {
mon_segment_warn(rc, mon_dcss_name);
return -EINVAL;
rc = -EINVAL;
goto out_iucv;
}
dcss_mkname(mon_dcss_name, &user_data_connect[8]);
@ -634,14 +616,16 @@ mon_init(void)
out:
segment_unload(mon_dcss_name);
out_iucv:
iucv_unregister(&monreader_iucv_handler, 1);
return rc;
}
static void __exit
mon_exit(void)
static void __exit mon_exit(void)
{
segment_unload(mon_dcss_name);
WARN_ON(misc_deregister(&mon_dev) != 0);
iucv_unregister(&monreader_iucv_handler, 1);
return;
}

View file

@ -67,8 +67,8 @@ static int monwrite_diag(struct monwrite_hdr *myhdr, char *buffer, int fcn)
return -EINVAL;
}
static inline struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv,
struct monwrite_hdr *monhdr)
static struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv,
struct monwrite_hdr *monhdr)
{
struct mon_buf *entry, *next;

View file

@ -29,7 +29,7 @@
#include <linux/device.h>
#include <linux/mutex.h>
struct class *class3270;
static struct class *class3270;
/* The main 3270 data structure. */
struct raw3270 {
@ -86,7 +86,7 @@ DECLARE_WAIT_QUEUE_HEAD(raw3270_wait_queue);
/*
* Encode array for 12 bit 3270 addresses.
*/
unsigned char raw3270_ebcgraf[64] = {
static unsigned char raw3270_ebcgraf[64] = {
0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,

View file

@ -59,7 +59,8 @@ static volatile enum sclp_init_state_t {
/* Internal state: is a request active at the sclp? */
static volatile enum sclp_running_state_t {
sclp_running_state_idle,
sclp_running_state_running
sclp_running_state_running,
sclp_running_state_reset_pending
} sclp_running_state = sclp_running_state_idle;
/* Internal state: is a read request pending? */
@ -88,15 +89,15 @@ static volatile enum sclp_mask_state_t {
/* Timeout intervals in seconds.*/
#define SCLP_BUSY_INTERVAL 10
#define SCLP_RETRY_INTERVAL 15
#define SCLP_RETRY_INTERVAL 30
static void sclp_process_queue(void);
static int sclp_init_mask(int calculate);
static int sclp_init(void);
/* Perform service call. Return 0 on success, non-zero otherwise. */
static int
service_call(sclp_cmdw_t command, void *sccb)
int
sclp_service_call(sclp_cmdw_t command, void *sccb)
{
int cc;
@ -113,19 +114,17 @@ service_call(sclp_cmdw_t command, void *sccb)
return 0;
}
/* Request timeout handler. Restart the request queue. If DATA is non-zero,
* force restart of running request. */
static void
sclp_request_timeout(unsigned long data)
{
unsigned long flags;
static inline void __sclp_make_read_req(void);
if (data) {
spin_lock_irqsave(&sclp_lock, flags);
sclp_running_state = sclp_running_state_idle;
spin_unlock_irqrestore(&sclp_lock, flags);
static void
__sclp_queue_read_req(void)
{
if (sclp_reading_state == sclp_reading_state_idle) {
sclp_reading_state = sclp_reading_state_reading;
__sclp_make_read_req();
/* Add request to head of queue */
list_add(&sclp_read_req.list, &sclp_req_queue);
}
sclp_process_queue();
}
/* Set up request retry timer. Called while sclp_lock is locked. */
@ -140,6 +139,29 @@ __sclp_set_request_timer(unsigned long time, void (*function)(unsigned long),
add_timer(&sclp_request_timer);
}
/* Request timeout handler. Restart the request queue. If DATA is non-zero,
* force restart of running request. */
static void
sclp_request_timeout(unsigned long data)
{
unsigned long flags;
spin_lock_irqsave(&sclp_lock, flags);
if (data) {
if (sclp_running_state == sclp_running_state_running) {
/* Break running state and queue NOP read event request
* to get a defined interface state. */
__sclp_queue_read_req();
sclp_running_state = sclp_running_state_idle;
}
} else {
__sclp_set_request_timer(SCLP_BUSY_INTERVAL * HZ,
sclp_request_timeout, 0);
}
spin_unlock_irqrestore(&sclp_lock, flags);
sclp_process_queue();
}
/* Try to start a request. Return zero if the request was successfully
* started or if it will be started at a later time. Return non-zero otherwise.
* Called while sclp_lock is locked. */
@ -151,7 +173,7 @@ __sclp_start_request(struct sclp_req *req)
if (sclp_running_state != sclp_running_state_idle)
return 0;
del_timer(&sclp_request_timer);
rc = service_call(req->command, req->sccb);
rc = sclp_service_call(req->command, req->sccb);
req->start_count++;
if (rc == 0) {
@ -191,7 +213,15 @@ sclp_process_queue(void)
rc = __sclp_start_request(req);
if (rc == 0)
break;
/* Request failed. */
/* Request failed */
if (req->start_count > 1) {
/* Cannot abort already submitted request - could still
* be active at the SCLP */
__sclp_set_request_timer(SCLP_BUSY_INTERVAL * HZ,
sclp_request_timeout, 0);
break;
}
/* Post-processing for aborted request */
list_del(&req->list);
if (req->callback) {
spin_unlock_irqrestore(&sclp_lock, flags);
@ -221,7 +251,8 @@ sclp_add_request(struct sclp_req *req)
list_add_tail(&req->list, &sclp_req_queue);
rc = 0;
/* Start if request is first in list */
if (req->list.prev == &sclp_req_queue) {
if (sclp_running_state == sclp_running_state_idle &&
req->list.prev == &sclp_req_queue) {
rc = __sclp_start_request(req);
if (rc)
list_del(&req->list);
@ -294,7 +325,7 @@ __sclp_make_read_req(void)
sccb = (struct sccb_header *) sclp_read_sccb;
clear_page(sccb);
memset(&sclp_read_req, 0, sizeof(struct sclp_req));
sclp_read_req.command = SCLP_CMDW_READDATA;
sclp_read_req.command = SCLP_CMDW_READ_EVENT_DATA;
sclp_read_req.status = SCLP_REQ_QUEUED;
sclp_read_req.start_count = 0;
sclp_read_req.callback = sclp_read_cb;
@ -334,6 +365,8 @@ sclp_interrupt_handler(__u16 code)
finished_sccb = S390_lowcore.ext_params & 0xfffffff8;
evbuf_pending = S390_lowcore.ext_params & 0x3;
if (finished_sccb) {
del_timer(&sclp_request_timer);
sclp_running_state = sclp_running_state_reset_pending;
req = __sclp_find_req(finished_sccb);
if (req) {
/* Request post-processing */
@ -348,13 +381,8 @@ sclp_interrupt_handler(__u16 code)
sclp_running_state = sclp_running_state_idle;
}
if (evbuf_pending && sclp_receive_mask != 0 &&
sclp_reading_state == sclp_reading_state_idle &&
sclp_activation_state == sclp_activation_state_active ) {
sclp_reading_state = sclp_reading_state_reading;
__sclp_make_read_req();
/* Add request to head of queue */
list_add(&sclp_read_req.list, &sclp_req_queue);
}
sclp_activation_state == sclp_activation_state_active)
__sclp_queue_read_req();
spin_unlock(&sclp_lock);
sclp_process_queue();
}
@ -374,6 +402,7 @@ sclp_sync_wait(void)
unsigned long flags;
unsigned long cr0, cr0_sync;
u64 timeout;
int irq_context;
/* We'll be disabling timer interrupts, so we need a custom timeout
* mechanism */
@ -386,7 +415,9 @@ sclp_sync_wait(void)
}
local_irq_save(flags);
/* Prevent bottom half from executing once we force interrupts open */
local_bh_disable();
irq_context = in_interrupt();
if (!irq_context)
local_bh_disable();
/* Enable service-signal interruption, disable timer interrupts */
trace_hardirqs_on();
__ctl_store(cr0, 0, 0);
@ -402,19 +433,19 @@ sclp_sync_wait(void)
get_clock() > timeout &&
del_timer(&sclp_request_timer))
sclp_request_timer.function(sclp_request_timer.data);
barrier();
cpu_relax();
}
local_irq_disable();
__ctl_load(cr0, 0, 0);
_local_bh_enable();
if (!irq_context)
_local_bh_enable();
local_irq_restore(flags);
}
EXPORT_SYMBOL(sclp_sync_wait);
/* Dispatch changes in send and receive mask to registered listeners. */
static inline void
static void
sclp_dispatch_state_change(void)
{
struct list_head *l;
@ -597,7 +628,7 @@ __sclp_make_init_req(u32 receive_mask, u32 send_mask)
sccb = (struct init_sccb *) sclp_init_sccb;
clear_page(sccb);
memset(&sclp_init_req, 0, sizeof(struct sclp_req));
sclp_init_req.command = SCLP_CMDW_WRITEMASK;
sclp_init_req.command = SCLP_CMDW_WRITE_EVENT_MASK;
sclp_init_req.status = SCLP_REQ_FILLED;
sclp_init_req.start_count = 0;
sclp_init_req.callback = NULL;
@ -800,7 +831,7 @@ sclp_check_interface(void)
for (retry = 0; retry <= SCLP_INIT_RETRY; retry++) {
__sclp_make_init_req(0, 0);
sccb = (struct init_sccb *) sclp_init_req.sccb;
rc = service_call(sclp_init_req.command, sccb);
rc = sclp_service_call(sclp_init_req.command, sccb);
if (rc == -EIO)
break;
sclp_init_req.status = SCLP_REQ_RUNNING;

View file

@ -12,7 +12,7 @@
#include <linux/types.h>
#include <linux/list.h>
#include <asm/sclp.h>
#include <asm/ebcdic.h>
/* maximum number of pages concerning our own memory management */
@ -49,9 +49,11 @@
typedef unsigned int sclp_cmdw_t;
#define SCLP_CMDW_READDATA 0x00770005
#define SCLP_CMDW_WRITEDATA 0x00760005
#define SCLP_CMDW_WRITEMASK 0x00780005
#define SCLP_CMDW_READ_EVENT_DATA 0x00770005
#define SCLP_CMDW_WRITE_EVENT_DATA 0x00760005
#define SCLP_CMDW_WRITE_EVENT_MASK 0x00780005
#define SCLP_CMDW_READ_SCP_INFO 0x00020001
#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
#define GDS_ID_MDSMU 0x1310
#define GDS_ID_MDSRouteInfo 0x1311
@ -66,13 +68,6 @@ typedef unsigned int sclp_cmdw_t;
typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */
struct sccb_header {
u16 length;
u8 function_code;
u8 control_mask[3];
u16 response_code;
} __attribute__((packed));
struct gds_subvector {
u8 length;
u8 key;
@ -131,6 +126,7 @@ void sclp_unregister(struct sclp_register *reg);
int sclp_remove_processed(struct sccb_header *sccb);
int sclp_deactivate(void);
int sclp_reactivate(void);
int sclp_service_call(sclp_cmdw_t command, void *sccb);
/* useful inlines */

View file

@ -66,7 +66,7 @@ sclp_conbuf_callback(struct sclp_buffer *buffer, int rc)
} while (buffer && sclp_emit_buffer(buffer, sclp_conbuf_callback));
}
static inline void
static void
sclp_conbuf_emit(void)
{
struct sclp_buffer* buffer;

View file

@ -169,7 +169,7 @@ cpi_prepare_req(void)
}
/* prepare request data structure presented to SCLP driver */
req->command = SCLP_CMDW_WRITEDATA;
req->command = SCLP_CMDW_WRITE_EVENT_DATA;
req->sccb = sccb;
req->status = SCLP_REQ_FILLED;
req->callback = cpi_callback;

View file

@ -0,0 +1,57 @@
/*
* drivers/s390/char/sclp_info.c
*
* Copyright IBM Corp. 2007
* Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
*/
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <asm/sclp.h>
#include "sclp.h"
struct sclp_readinfo_sccb s390_readinfo_sccb;
void __init sclp_readinfo_early(void)
{
sclp_cmdw_t command;
struct sccb_header *sccb;
int ret;
__ctl_set_bit(0, 9); /* enable service signal subclass mask */
sccb = &s390_readinfo_sccb.header;
command = SCLP_CMDW_READ_SCP_INFO_FORCED;
while (1) {
u16 response;
memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb));
sccb->length = sizeof(s390_readinfo_sccb);
sccb->control_mask[2] = 0x80;
ret = sclp_service_call(command, &s390_readinfo_sccb);
if (ret == -EIO)
goto out;
if (ret == -EBUSY)
continue;
__load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT |
PSW_MASK_WAIT | PSW_DEFAULT_KEY);
local_irq_disable();
barrier();
response = sccb->response_code;
if (response == 0x10)
break;
if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO)
break;
command = SCLP_CMDW_READ_SCP_INFO;
}
out:
__ctl_clear_bit(0, 9); /* disable service signal subclass mask */
}

View file

@ -460,7 +460,7 @@ sclp_emit_buffer(struct sclp_buffer *buffer,
sccb->msg_buf.header.type = EvTyp_PMsgCmd;
else
return -ENOSYS;
buffer->request.command = SCLP_CMDW_WRITEDATA;
buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA;
buffer->request.status = SCLP_REQ_FILLED;
buffer->request.callback = sclp_writedata_callback;
buffer->request.callback_data = buffer;

View file

@ -721,7 +721,7 @@ static const struct tty_operations sclp_ops = {
.ioctl = sclp_tty_ioctl,
};
int __init
static int __init
sclp_tty_init(void)
{
struct tty_driver *driver;

View file

@ -207,7 +207,7 @@ __sclp_vt220_emit(struct sclp_vt220_request *request)
request->sclp_req.status = SCLP_REQ_FAILED;
return -EIO;
}
request->sclp_req.command = SCLP_CMDW_WRITEDATA;
request->sclp_req.command = SCLP_CMDW_WRITE_EVENT_DATA;
request->sclp_req.status = SCLP_REQ_FILLED;
request->sclp_req.callback = sclp_vt220_callback;
request->sclp_req.callback_data = (void *) request;
@ -669,7 +669,7 @@ static const struct tty_operations sclp_vt220_ops = {
/*
* Register driver with SCLP and Linux and initialize internal tty structures.
*/
int __init
static int __init
sclp_vt220_tty_init(void)
{
struct tty_driver *driver;

View file

@ -3,7 +3,7 @@
* tape device driver for 3480/3490E/3590 tapes.
*
* S390 and zSeries version
* Copyright (C) 2001,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright IBM Corp. 2001,2006
* Author(s): Carsten Otte <cotte@de.ibm.com>
* Tuan Ngo-Anh <ngoanh@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@ -99,7 +99,11 @@ enum tape_op {
TO_DIS, /* Tape display */
TO_ASSIGN, /* Assign tape to channel path */
TO_UNASSIGN, /* Unassign tape from channel path */
TO_SIZE /* #entries in tape_op_t */
TO_CRYPT_ON, /* Enable encrpytion */
TO_CRYPT_OFF, /* Disable encrpytion */
TO_KEKL_SET, /* Set KEK label */
TO_KEKL_QUERY, /* Query KEK label */
TO_SIZE, /* #entries in tape_op_t */
};
/* Forward declaration */
@ -112,6 +116,7 @@ enum tape_request_status {
TAPE_REQUEST_IN_IO, /* request is currently in IO */
TAPE_REQUEST_DONE, /* request is completed. */
TAPE_REQUEST_CANCEL, /* request should be canceled. */
TAPE_REQUEST_LONG_BUSY, /* request has to be restarted after long busy */
};
/* Tape CCW request */
@ -164,10 +169,11 @@ struct tape_discipline {
* The discipline irq function either returns an error code (<0) which
* means that the request has failed with an error or one of the following:
*/
#define TAPE_IO_SUCCESS 0 /* request successful */
#define TAPE_IO_PENDING 1 /* request still running */
#define TAPE_IO_RETRY 2 /* retry to current request */
#define TAPE_IO_STOP 3 /* stop the running request */
#define TAPE_IO_SUCCESS 0 /* request successful */
#define TAPE_IO_PENDING 1 /* request still running */
#define TAPE_IO_RETRY 2 /* retry to current request */
#define TAPE_IO_STOP 3 /* stop the running request */
#define TAPE_IO_LONG_BUSY 4 /* delay the running request */
/* Char Frontend Data */
struct tape_char_data {
@ -242,6 +248,10 @@ struct tape_device {
/* Function to start or stop the next request later. */
struct delayed_work tape_dnr;
/* Timer for long busy */
struct timer_list lb_timeout;
};
/* Externals from tape_core.c */

View file

@ -2,7 +2,7 @@
* drivers/s390/char/tape_3590.c
* tape device discipline for 3590 tapes.
*
* Copyright (C) IBM Corp. 2001,2006
* Copyright IBM Corp. 2001,2006
* Author(s): Stefan Bader <shbader@de.ibm.com>
* Michael Holzheu <holzheu@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bio.h>
#include <asm/ebcdic.h>
#define TAPE_DBF_AREA tape_3590_dbf
@ -30,7 +31,7 @@ EXPORT_SYMBOL(TAPE_DBF_AREA);
* - Read Device (buffered) log: BRA
* - Read Library log: BRA
* - Swap Devices: BRA
* - Long Busy: BRA
* - Long Busy: implemented
* - Special Intercept: BRA
* - Read Alternate: implemented
*******************************************************************/
@ -94,6 +95,332 @@ static const char *tape_3590_msg[TAPE_3590_MAX_MSG] = {
[0xae] = "Subsystem environmental alert",
};
static int crypt_supported(struct tape_device *device)
{
return TAPE390_CRYPT_SUPPORTED(TAPE_3590_CRYPT_INFO(device));
}
static int crypt_enabled(struct tape_device *device)
{
return TAPE390_CRYPT_ON(TAPE_3590_CRYPT_INFO(device));
}
static void ext_to_int_kekl(struct tape390_kekl *in,
struct tape3592_kekl *out)
{
int i;
memset(out, 0, sizeof(*out));
if (in->type == TAPE390_KEKL_TYPE_HASH)
out->flags |= 0x40;
if (in->type_on_tape == TAPE390_KEKL_TYPE_HASH)
out->flags |= 0x80;
strncpy(out->label, in->label, 64);
for (i = strlen(in->label); i < sizeof(out->label); i++)
out->label[i] = ' ';
ASCEBC(out->label, sizeof(out->label));
}
static void int_to_ext_kekl(struct tape3592_kekl *in,
struct tape390_kekl *out)
{
memset(out, 0, sizeof(*out));
if(in->flags & 0x40)
out->type = TAPE390_KEKL_TYPE_HASH;
else
out->type = TAPE390_KEKL_TYPE_LABEL;
if(in->flags & 0x80)
out->type_on_tape = TAPE390_KEKL_TYPE_HASH;
else
out->type_on_tape = TAPE390_KEKL_TYPE_LABEL;
memcpy(out->label, in->label, sizeof(in->label));
EBCASC(out->label, sizeof(in->label));
strstrip(out->label);
}
static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in,
struct tape390_kekl_pair *out)
{
if (in->count == 0) {
out->kekl[0].type = TAPE390_KEKL_TYPE_NONE;
out->kekl[0].type_on_tape = TAPE390_KEKL_TYPE_NONE;
out->kekl[1].type = TAPE390_KEKL_TYPE_NONE;
out->kekl[1].type_on_tape = TAPE390_KEKL_TYPE_NONE;
} else if (in->count == 1) {
int_to_ext_kekl(&in->kekl[0], &out->kekl[0]);
out->kekl[1].type = TAPE390_KEKL_TYPE_NONE;
out->kekl[1].type_on_tape = TAPE390_KEKL_TYPE_NONE;
} else if (in->count == 2) {
int_to_ext_kekl(&in->kekl[0], &out->kekl[0]);
int_to_ext_kekl(&in->kekl[1], &out->kekl[1]);
} else {
printk("Invalid KEKL number: %d\n", in->count);
BUG();
}
}
static int check_ext_kekl(struct tape390_kekl *kekl)
{
if (kekl->type == TAPE390_KEKL_TYPE_NONE)
goto invalid;
if (kekl->type > TAPE390_KEKL_TYPE_HASH)
goto invalid;
if (kekl->type_on_tape == TAPE390_KEKL_TYPE_NONE)
goto invalid;
if (kekl->type_on_tape > TAPE390_KEKL_TYPE_HASH)
goto invalid;
if ((kekl->type == TAPE390_KEKL_TYPE_HASH) &&
(kekl->type_on_tape == TAPE390_KEKL_TYPE_LABEL))
goto invalid;
return 0;
invalid:
return -EINVAL;
}
static int check_ext_kekl_pair(struct tape390_kekl_pair *kekls)
{
if (check_ext_kekl(&kekls->kekl[0]))
goto invalid;
if (check_ext_kekl(&kekls->kekl[1]))
goto invalid;
return 0;
invalid:
return -EINVAL;
}
/*
* Query KEKLs
*/
static int tape_3592_kekl_query(struct tape_device *device,
struct tape390_kekl_pair *ext_kekls)
{
struct tape_request *request;
struct tape3592_kekl_query_order *order;
struct tape3592_kekl_query_data *int_kekls;
int rc;
DBF_EVENT(6, "tape3592_kekl_query\n");
int_kekls = kmalloc(sizeof(*int_kekls), GFP_KERNEL|GFP_DMA);
if (!int_kekls)
return -ENOMEM;
request = tape_alloc_request(2, sizeof(*order));
if (IS_ERR(request)) {
rc = PTR_ERR(request);
goto fail_malloc;
}
order = request->cpdata;
memset(order,0,sizeof(*order));
order->code = 0xe2;
order->max_count = 2;
request->op = TO_KEKL_QUERY;
tape_ccw_cc(request->cpaddr, PERF_SUBSYS_FUNC, sizeof(*order), order);
tape_ccw_end(request->cpaddr + 1, READ_SS_DATA, sizeof(*int_kekls),
int_kekls);
rc = tape_do_io(device, request);
if (rc)
goto fail_request;
int_to_ext_kekl_pair(&int_kekls->kekls, ext_kekls);
rc = 0;
fail_request:
tape_free_request(request);
fail_malloc:
kfree(int_kekls);
return rc;
}
/*
* IOCTL: Query KEKLs
*/
static int tape_3592_ioctl_kekl_query(struct tape_device *device,
unsigned long arg)
{
int rc;
struct tape390_kekl_pair *ext_kekls;
DBF_EVENT(6, "tape_3592_ioctl_kekl_query\n");
if (!crypt_supported(device))
return -ENOSYS;
if (!crypt_enabled(device))
return -EUNATCH;
ext_kekls = kmalloc(sizeof(*ext_kekls), GFP_KERNEL);
if (!ext_kekls)
return -ENOMEM;
rc = tape_3592_kekl_query(device, ext_kekls);
if (rc != 0)
goto fail;
if (copy_to_user((char __user *) arg, ext_kekls, sizeof(*ext_kekls))) {
rc = -EFAULT;
goto fail;
}
rc = 0;
fail:
kfree(ext_kekls);
return rc;
}
static int tape_3590_mttell(struct tape_device *device, int mt_count);
/*
* Set KEKLs
*/
static int tape_3592_kekl_set(struct tape_device *device,
struct tape390_kekl_pair *ext_kekls)
{
struct tape_request *request;
struct tape3592_kekl_set_order *order;
DBF_EVENT(6, "tape3592_kekl_set\n");
if (check_ext_kekl_pair(ext_kekls)) {
DBF_EVENT(6, "invalid kekls\n");
return -EINVAL;
}
if (tape_3590_mttell(device, 0) != 0)
return -EBADSLT;
request = tape_alloc_request(1, sizeof(*order));
if (IS_ERR(request))
return PTR_ERR(request);
order = request->cpdata;
memset(order, 0, sizeof(*order));
order->code = 0xe3;
order->kekls.count = 2;
ext_to_int_kekl(&ext_kekls->kekl[0], &order->kekls.kekl[0]);
ext_to_int_kekl(&ext_kekls->kekl[1], &order->kekls.kekl[1]);
request->op = TO_KEKL_SET;
tape_ccw_end(request->cpaddr, PERF_SUBSYS_FUNC, sizeof(*order), order);
return tape_do_io_free(device, request);
}
/*
* IOCTL: Set KEKLs
*/
static int tape_3592_ioctl_kekl_set(struct tape_device *device,
unsigned long arg)
{
int rc;
struct tape390_kekl_pair *ext_kekls;
DBF_EVENT(6, "tape_3592_ioctl_kekl_set\n");
if (!crypt_supported(device))
return -ENOSYS;
if (!crypt_enabled(device))
return -EUNATCH;
ext_kekls = kmalloc(sizeof(*ext_kekls), GFP_KERNEL);
if (!ext_kekls)
return -ENOMEM;
if (copy_from_user(ext_kekls, (char __user *)arg, sizeof(*ext_kekls))) {
rc = -EFAULT;
goto out;
}
rc = tape_3592_kekl_set(device, ext_kekls);
out:
kfree(ext_kekls);
return rc;
}
/*
* Enable encryption
*/
static int tape_3592_enable_crypt(struct tape_device *device)
{
struct tape_request *request;
char *data;
DBF_EVENT(6, "tape_3592_enable_crypt\n");
if (!crypt_supported(device))
return -ENOSYS;
request = tape_alloc_request(2, 72);
if (IS_ERR(request))
return PTR_ERR(request);
data = request->cpdata;
memset(data,0,72);
data[0] = 0x05;
data[36 + 0] = 0x03;
data[36 + 1] = 0x03;
data[36 + 4] = 0x40;
data[36 + 6] = 0x01;
data[36 + 14] = 0x2f;
data[36 + 18] = 0xc3;
data[36 + 35] = 0x72;
request->op = TO_CRYPT_ON;
tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
return tape_do_io_free(device, request);
}
/*
* Disable encryption
*/
static int tape_3592_disable_crypt(struct tape_device *device)
{
struct tape_request *request;
char *data;
DBF_EVENT(6, "tape_3592_disable_crypt\n");
if (!crypt_supported(device))
return -ENOSYS;
request = tape_alloc_request(2, 72);
if (IS_ERR(request))
return PTR_ERR(request);
data = request->cpdata;
memset(data,0,72);
data[0] = 0x05;
data[36 + 0] = 0x03;
data[36 + 1] = 0x03;
data[36 + 35] = 0x32;
request->op = TO_CRYPT_OFF;
tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
return tape_do_io_free(device, request);
}
/*
* IOCTL: Set encryption status
*/
static int tape_3592_ioctl_crypt_set(struct tape_device *device,
unsigned long arg)
{
struct tape390_crypt_info info;
DBF_EVENT(6, "tape_3592_ioctl_crypt_set\n");
if (!crypt_supported(device))
return -ENOSYS;
if (copy_from_user(&info, (char __user *)arg, sizeof(info)))
return -EFAULT;
if (info.status & ~TAPE390_CRYPT_ON_MASK)
return -EINVAL;
if (info.status & TAPE390_CRYPT_ON_MASK)
return tape_3592_enable_crypt(device);
else
return tape_3592_disable_crypt(device);
}
static int tape_3590_sense_medium(struct tape_device *device);
/*
* IOCTL: Query enryption status
*/
static int tape_3592_ioctl_crypt_query(struct tape_device *device,
unsigned long arg)
{
DBF_EVENT(6, "tape_3592_ioctl_crypt_query\n");
if (!crypt_supported(device))
return -ENOSYS;
tape_3590_sense_medium(device);
if (copy_to_user((char __user *) arg, &TAPE_3590_CRYPT_INFO(device),
sizeof(TAPE_3590_CRYPT_INFO(device))))
return -EFAULT;
else
return 0;
}
/*
* 3590 IOCTL Overload
*/
@ -109,6 +436,14 @@ tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg)
return tape_std_display(device, &disp);
}
case TAPE390_KEKL_SET:
return tape_3592_ioctl_kekl_set(device, arg);
case TAPE390_KEKL_QUERY:
return tape_3592_ioctl_kekl_query(device, arg);
case TAPE390_CRYPT_SET:
return tape_3592_ioctl_crypt_set(device, arg);
case TAPE390_CRYPT_QUERY:
return tape_3592_ioctl_crypt_query(device, arg);
default:
return -EINVAL; /* no additional ioctls */
}
@ -248,6 +583,12 @@ tape_3590_work_handler(struct work_struct *work)
case TO_READ_ATTMSG:
tape_3590_read_attmsg(p->device);
break;
case TO_CRYPT_ON:
tape_3592_enable_crypt(p->device);
break;
case TO_CRYPT_OFF:
tape_3592_disable_crypt(p->device);
break;
default:
DBF_EVENT(3, "T3590: work handler undefined for "
"operation 0x%02x\n", p->op);
@ -365,6 +706,33 @@ tape_3590_check_locate(struct tape_device *device, struct tape_request *request)
}
#endif
static void tape_3590_med_state_set(struct tape_device *device,
struct tape_3590_med_sense *sense)
{
struct tape390_crypt_info *c_info;
c_info = &TAPE_3590_CRYPT_INFO(device);
if (sense->masst == MSENSE_UNASSOCIATED) {
tape_med_state_set(device, MS_UNLOADED);
TAPE_3590_CRYPT_INFO(device).medium_status = 0;
return;
}
if (sense->masst != MSENSE_ASSOCIATED_MOUNT) {
PRINT_ERR("Unknown medium state: %x\n", sense->masst);
return;
}
tape_med_state_set(device, MS_LOADED);
c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK;
if (sense->flags & MSENSE_CRYPT_MASK) {
PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags);
c_info->medium_status |= TAPE390_MEDIUM_ENCRYPTED_MASK;
} else {
DBF_EVENT(6, "Medium is not encrypted %04x\n", sense->flags);
c_info->medium_status &= ~TAPE390_MEDIUM_ENCRYPTED_MASK;
}
}
/*
* The done handler is called at device/channel end and wakes up the sleeping
* process
@ -372,9 +740,10 @@ tape_3590_check_locate(struct tape_device *device, struct tape_request *request)
static int
tape_3590_done(struct tape_device *device, struct tape_request *request)
{
struct tape_3590_med_sense *sense;
struct tape_3590_disc_data *disc_data;
DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);
disc_data = device->discdata;
switch (request->op) {
case TO_BSB:
@ -394,13 +763,20 @@ tape_3590_done(struct tape_device *device, struct tape_request *request)
break;
case TO_RUN:
tape_med_state_set(device, MS_UNLOADED);
tape_3590_schedule_work(device, TO_CRYPT_OFF);
break;
case TO_MSEN:
sense = (struct tape_3590_med_sense *) request->cpdata;
if (sense->masst == MSENSE_UNASSOCIATED)
tape_med_state_set(device, MS_UNLOADED);
if (sense->masst == MSENSE_ASSOCIATED_MOUNT)
tape_med_state_set(device, MS_LOADED);
tape_3590_med_state_set(device, request->cpdata);
break;
case TO_CRYPT_ON:
TAPE_3590_CRYPT_INFO(device).status
|= TAPE390_CRYPT_ON_MASK;
*(device->modeset_byte) |= 0x03;
break;
case TO_CRYPT_OFF:
TAPE_3590_CRYPT_INFO(device).status
&= ~TAPE390_CRYPT_ON_MASK;
*(device->modeset_byte) &= ~0x03;
break;
case TO_RBI: /* RBI seems to succeed even without medium loaded. */
case TO_NOP: /* Same to NOP. */
@ -409,8 +785,9 @@ tape_3590_done(struct tape_device *device, struct tape_request *request)
case TO_DIS:
case TO_ASSIGN:
case TO_UNASSIGN:
break;
case TO_SIZE:
case TO_KEKL_SET:
case TO_KEKL_QUERY:
break;
}
return TAPE_IO_SUCCESS;
@ -540,10 +917,8 @@ static int
tape_3590_erp_long_busy(struct tape_device *device,
struct tape_request *request, struct irb *irb)
{
/* FIXME: how about WAITING for a minute ? */
PRINT_WARN("(%s): Device is busy! Please wait a minute!\n",
device->cdev->dev.bus_id);
return tape_3590_erp_basic(device, request, irb, -EBUSY);
DBF_EVENT(6, "Device is busy\n");
return TAPE_IO_LONG_BUSY;
}
/*
@ -951,6 +1326,34 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
device->cdev->dev.bus_id, sense->mc);
}
static int tape_3590_crypt_error(struct tape_device *device,
struct tape_request *request, struct irb *irb)
{
u8 cu_rc, ekm_rc1;
u16 ekm_rc2;
u32 drv_rc;
char *bus_id, *sense;
sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data;
bus_id = device->cdev->dev.bus_id;
cu_rc = sense[0];
drv_rc = *((u32*) &sense[5]) & 0xffffff;
ekm_rc1 = sense[9];
ekm_rc2 = *((u16*) &sense[10]);
if ((cu_rc == 0) && (ekm_rc2 == 0xee31))
/* key not defined on EKM */
return tape_3590_erp_basic(device, request, irb, -EKEYREJECTED);
if ((cu_rc == 1) || (cu_rc == 2))
/* No connection to EKM */
return tape_3590_erp_basic(device, request, irb, -ENOTCONN);
PRINT_ERR("(%s): Unable to get encryption key from EKM\n", bus_id);
PRINT_ERR("(%s): CU=%02X DRIVE=%06X EKM=%02X:%04X\n", bus_id, cu_rc,
drv_rc, ekm_rc1, ekm_rc2);
return tape_3590_erp_basic(device, request, irb, -ENOKEY);
}
/*
* 3590 error Recovery routine:
* If possible, it tries to recover from the error. If this is not possible,
@ -979,6 +1382,8 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
sense = (struct tape_3590_sense *) irb->ecw;
DBF_EVENT(6, "Unit Check: RQC = %x\n", sense->rc_rqc);
/*
* First check all RC-QRCs where we want to do something special
* - "break": basic error recovery is done
@ -999,6 +1404,8 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
case 0x2231:
tape_3590_print_era_msg(device, irb);
return tape_3590_erp_special_interrupt(device, request, irb);
case 0x2240:
return tape_3590_crypt_error(device, request, irb);
case 0x3010:
DBF_EVENT(2, "(%08x): Backward at Beginning of Partition\n",
@ -1020,6 +1427,7 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
DBF_EVENT(2, "(%08x): Rewind Unload complete\n",
device->cdev_id);
tape_med_state_set(device, MS_UNLOADED);
tape_3590_schedule_work(device, TO_CRYPT_OFF);
return tape_3590_erp_basic(device, request, irb, 0);
case 0x4010:
@ -1030,9 +1438,15 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
PRINT_WARN("(%s): Tape operation when medium not loaded\n",
device->cdev->dev.bus_id);
tape_med_state_set(device, MS_UNLOADED);
tape_3590_schedule_work(device, TO_CRYPT_OFF);
return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
case 0x4012: /* Device Long Busy */
/* XXX: Also use long busy handling here? */
DBF_EVENT(6, "(%08x): LONG BUSY\n", device->cdev_id);
tape_3590_print_era_msg(device, irb);
return tape_3590_erp_basic(device, request, irb, -EBUSY);
case 0x4014:
DBF_EVENT(6, "(%08x): Crypto LONG BUSY\n", device->cdev_id);
return tape_3590_erp_long_busy(device, request, irb);
case 0x5010:
@ -1064,6 +1478,7 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
case 0x5120:
case 0x1120:
tape_med_state_set(device, MS_UNLOADED);
tape_3590_schedule_work(device, TO_CRYPT_OFF);
return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
case 0x6020:
@ -1142,21 +1557,47 @@ tape_3590_setup_device(struct tape_device *device)
{
int rc;
struct tape_3590_disc_data *data;
char *rdc_data;
DBF_EVENT(6, "3590 device setup\n");
data = kmalloc(sizeof(struct tape_3590_disc_data),
GFP_KERNEL | GFP_DMA);
data = kzalloc(sizeof(struct tape_3590_disc_data), GFP_KERNEL | GFP_DMA);
if (data == NULL)
return -ENOMEM;
data->read_back_op = READ_PREVIOUS;
device->discdata = data;
if ((rc = tape_std_assign(device)) == 0) {
/* Try to find out if medium is loaded */
if ((rc = tape_3590_sense_medium(device)) != 0)
DBF_LH(3, "3590 medium sense returned %d\n", rc);
rdc_data = kmalloc(64, GFP_KERNEL | GFP_DMA);
if (!rdc_data) {
rc = -ENOMEM;
goto fail_kmalloc;
}
rc = read_dev_chars(device->cdev, (void**)&rdc_data, 64);
if (rc) {
DBF_LH(3, "Read device characteristics failed!\n");
goto fail_kmalloc;
}
rc = tape_std_assign(device);
if (rc)
goto fail_rdc_data;
if (rdc_data[31] == 0x13) {
PRINT_INFO("Device has crypto support\n");
data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK;
tape_3592_disable_crypt(device);
} else {
DBF_EVENT(6, "Device has NO crypto support\n");
}
/* Try to find out if medium is loaded */
rc = tape_3590_sense_medium(device);
if (rc) {
DBF_LH(3, "3590 medium sense returned %d\n", rc);
goto fail_rdc_data;
}
return 0;
fail_rdc_data:
kfree(rdc_data);
fail_kmalloc:
kfree(data);
return rc;
}

View file

@ -2,7 +2,7 @@
* drivers/s390/char/tape_3590.h
* tape device discipline for 3590 tapes.
*
* Copyright (C) IBM Corp. 2001,2006
* Copyright IBM Corp. 2001,2006
* Author(s): Stefan Bader <shbader@de.ibm.com>
* Michael Holzheu <holzheu@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@ -38,16 +38,22 @@
#define MSENSE_UNASSOCIATED 0x00
#define MSENSE_ASSOCIATED_MOUNT 0x01
#define MSENSE_ASSOCIATED_UMOUNT 0x02
#define MSENSE_CRYPT_MASK 0x00000010
#define TAPE_3590_MAX_MSG 0xb0
/* Datatypes */
struct tape_3590_disc_data {
unsigned char modeset_byte;
struct tape390_crypt_info crypt_info;
int read_back_op;
};
#define TAPE_3590_CRYPT_INFO(device) \
((struct tape_3590_disc_data*)(device->discdata))->crypt_info
#define TAPE_3590_READ_BACK_OP(device) \
((struct tape_3590_disc_data*)(device->discdata))->read_back_op
struct tape_3590_sense {
unsigned int command_rej:1;
@ -118,7 +124,48 @@ struct tape_3590_sense {
struct tape_3590_med_sense {
unsigned int macst:4;
unsigned int masst:4;
char pad[127];
char pad1[7];
unsigned int flags;
char pad2[116];
} __attribute__ ((packed));
/* Datastructures for 3592 encryption support */
struct tape3592_kekl {
__u8 flags;
char label[64];
} __attribute__ ((packed));
struct tape3592_kekl_pair {
__u8 count;
struct tape3592_kekl kekl[2];
} __attribute__ ((packed));
struct tape3592_kekl_query_data {
__u16 len;
__u8 fmt;
__u8 mc;
__u32 id;
__u8 flags;
struct tape3592_kekl_pair kekls;
char reserved[116];
} __attribute__ ((packed));
struct tape3592_kekl_query_order {
__u8 code;
__u8 flags;
char reserved1[2];
__u8 max_count;
char reserved2[35];
} __attribute__ ((packed));
struct tape3592_kekl_set_order {
__u8 code;
__u8 flags;
char reserved1[2];
__u8 op;
struct tape3592_kekl_pair kekls;
char reserved2[120];
} __attribute__ ((packed));
#endif /* _TAPE_3590_H */

View file

@ -73,7 +73,7 @@ tapeblock_trigger_requeue(struct tape_device *device)
/*
* Post finished request.
*/
static inline void
static void
tapeblock_end_request(struct request *req, int uptodate)
{
if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
@ -108,7 +108,7 @@ __tapeblock_end_request(struct tape_request *ccw_req, void *data)
/*
* Feed the tape device CCW queue with requests supplied in a list.
*/
static inline int
static int
tapeblock_start_request(struct tape_device *device, struct request *req)
{
struct tape_request * ccw_req;

View file

@ -3,7 +3,7 @@
* character device frontend for tape device driver
*
* S390 and zSeries version
* Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright IBM Corp. 2001,2006
* Author(s): Carsten Otte <cotte@de.ibm.com>
* Michael Holzheu <holzheu@de.ibm.com>
* Tuan Ngo-Anh <ngoanh@de.ibm.com>
@ -89,22 +89,7 @@ tapechar_cleanup_device(struct tape_device *device)
device->nt = NULL;
}
/*
* Terminate write command (we write two TMs and skip backward over last)
* This ensures that the tape is always correctly terminated.
* When the user writes afterwards a new file, he will overwrite the
* second TM and therefore one TM will remain to separate the
* two files on the tape...
*/
static inline void
tapechar_terminate_write(struct tape_device *device)
{
if (tape_mtop(device, MTWEOF, 1) == 0 &&
tape_mtop(device, MTWEOF, 1) == 0)
tape_mtop(device, MTBSR, 1);
}
static inline int
static int
tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
{
struct idal_buffer *new;
@ -137,7 +122,7 @@ tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
/*
* Tape device read function
*/
ssize_t
static ssize_t
tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
{
struct tape_device *device;
@ -201,7 +186,7 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
/*
* Tape device write function
*/
ssize_t
static ssize_t
tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos)
{
struct tape_device *device;
@ -291,7 +276,7 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t
/*
* Character frontend tape device open function.
*/
int
static int
tapechar_open (struct inode *inode, struct file *filp)
{
struct tape_device *device;
@ -326,7 +311,7 @@ tapechar_open (struct inode *inode, struct file *filp)
* Character frontend tape device release function.
*/
int
static int
tapechar_release(struct inode *inode, struct file *filp)
{
struct tape_device *device;

View file

@ -3,7 +3,7 @@
* basic function of the tape device driver
*
* S390 and zSeries version
* Copyright (C) 2001,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright IBM Corp. 2001,2006
* Author(s): Carsten Otte <cotte@de.ibm.com>
* Michael Holzheu <holzheu@de.ibm.com>
* Tuan Ngo-Anh <ngoanh@de.ibm.com>
@ -26,9 +26,11 @@
#include "tape_std.h"
#define PRINTK_HEADER "TAPE_CORE: "
#define LONG_BUSY_TIMEOUT 180 /* seconds */
static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
static void tape_delayed_next_request(struct work_struct *);
static void tape_long_busy_timeout(unsigned long data);
/*
* One list to contain all tape devices of all disciplines, so
@ -69,10 +71,12 @@ const char *tape_op_verbose[TO_SIZE] =
[TO_LOAD] = "LOA", [TO_READ_CONFIG] = "RCF",
[TO_READ_ATTMSG] = "RAT",
[TO_DIS] = "DIS", [TO_ASSIGN] = "ASS",
[TO_UNASSIGN] = "UAS"
[TO_UNASSIGN] = "UAS", [TO_CRYPT_ON] = "CON",
[TO_CRYPT_OFF] = "COF", [TO_KEKL_SET] = "KLS",
[TO_KEKL_QUERY] = "KLQ",
};
static inline int
static int
busid_to_int(char *bus_id)
{
int dec;
@ -252,7 +256,7 @@ tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
/*
* Stop running ccw. Has to be called with the device lock held.
*/
static inline int
static int
__tape_cancel_io(struct tape_device *device, struct tape_request *request)
{
int retries;
@ -346,6 +350,9 @@ tape_generic_online(struct tape_device *device,
return -EINVAL;
}
init_timer(&device->lb_timeout);
device->lb_timeout.function = tape_long_busy_timeout;
/* Let the discipline have a go at the device. */
device->discipline = discipline;
if (!try_module_get(discipline->owner)) {
@ -385,7 +392,7 @@ out:
return rc;
}
static inline void
static void
tape_cleanup_device(struct tape_device *device)
{
tapeblock_cleanup_device(device);
@ -563,7 +570,7 @@ tape_generic_probe(struct ccw_device *cdev)
return ret;
}
static inline void
static void
__tape_discard_requests(struct tape_device *device)
{
struct tape_request * request;
@ -703,7 +710,7 @@ tape_free_request (struct tape_request * request)
kfree(request);
}
static inline int
static int
__tape_start_io(struct tape_device *device, struct tape_request *request)
{
int rc;
@ -733,7 +740,7 @@ __tape_start_io(struct tape_device *device, struct tape_request *request)
return rc;
}
static inline void
static void
__tape_start_next_request(struct tape_device *device)
{
struct list_head *l, *n;
@ -801,7 +808,23 @@ tape_delayed_next_request(struct work_struct *work)
spin_unlock_irq(get_ccwdev_lock(device->cdev));
}
static inline void
static void tape_long_busy_timeout(unsigned long data)
{
struct tape_request *request;
struct tape_device *device;
device = (struct tape_device *) data;
spin_lock_irq(get_ccwdev_lock(device->cdev));
request = list_entry(device->req_queue.next, struct tape_request, list);
if (request->status != TAPE_REQUEST_LONG_BUSY)
BUG();
DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id);
__tape_start_next_request(device);
device->lb_timeout.data = (unsigned long) tape_put_device(device);
spin_unlock_irq(get_ccwdev_lock(device->cdev));
}
static void
__tape_end_request(
struct tape_device * device,
struct tape_request * request,
@ -878,7 +901,7 @@ tape_dump_sense_dbf(struct tape_device *device, struct tape_request *request,
* and starts it if the tape is idle. Has to be called with
* the device lock held.
*/
static inline int
static int
__tape_start_request(struct tape_device *device, struct tape_request *request)
{
int rc;
@ -1094,7 +1117,22 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
/* May be an unsolicited irq */
if(request != NULL)
request->rescnt = irb->scsw.count;
else if ((irb->scsw.dstat == 0x85 || irb->scsw.dstat == 0x80) &&
!list_empty(&device->req_queue)) {
/* Not Ready to Ready after long busy ? */
struct tape_request *req;
req = list_entry(device->req_queue.next,
struct tape_request, list);
if (req->status == TAPE_REQUEST_LONG_BUSY) {
DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id);
if (del_timer(&device->lb_timeout)) {
device->lb_timeout.data = (unsigned long)
tape_put_device(device);
__tape_start_next_request(device);
}
return;
}
}
if (irb->scsw.dstat != 0x0c) {
/* Set the 'ONLINE' flag depending on sense byte 1 */
if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE)
@ -1142,6 +1180,15 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
break;
case TAPE_IO_PENDING:
break;
case TAPE_IO_LONG_BUSY:
device->lb_timeout.data =
(unsigned long)tape_get_device_reference(device);
device->lb_timeout.expires = jiffies +
LONG_BUSY_TIMEOUT * HZ;
DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id);
add_timer(&device->lb_timeout);
request->status = TAPE_REQUEST_LONG_BUSY;
break;
case TAPE_IO_RETRY:
rc = __tape_start_io(device, request);
if (rc)

View file

@ -36,7 +36,7 @@
struct tty_driver *tty3270_driver;
static int tty3270_max_index;
struct raw3270_fn tty3270_fn;
static struct raw3270_fn tty3270_fn;
struct tty3270_cell {
unsigned char character;
@ -119,8 +119,7 @@ static void tty3270_update(struct tty3270 *);
/*
* Setup timeout for a device. On timeout trigger an update.
*/
void
tty3270_set_timer(struct tty3270 *tp, int expires)
static void tty3270_set_timer(struct tty3270 *tp, int expires)
{
if (expires == 0) {
if (timer_pending(&tp->timer) && del_timer(&tp->timer))
@ -841,7 +840,7 @@ tty3270_del_views(void)
}
}
struct raw3270_fn tty3270_fn = {
static struct raw3270_fn tty3270_fn = {
.activate = tty3270_activate,
.deactivate = tty3270_deactivate,
.intv = (void *) tty3270_irq,
@ -1754,8 +1753,7 @@ static const struct tty_operations tty3270_ops = {
.set_termios = tty3270_set_termios
};
void
tty3270_notifier(int index, int active)
static void tty3270_notifier(int index, int active)
{
if (active)
tty_register_device(tty3270_driver, index, NULL);
@ -1767,8 +1765,7 @@ tty3270_notifier(int index, int active)
* 3270 tty registration code called from tty_init().
* Most kernel services (incl. kmalloc) are available at this poimt.
*/
int __init
tty3270_init(void)
static int __init tty3270_init(void)
{
struct tty_driver *driver;
int ret;

View file

@ -3,7 +3,7 @@
* character device driver for reading z/VM system service records
*
*
* Copyright (C) 2004 IBM Corporation
* Copyright 2004 IBM Corporation
* character device driver for reading z/VM system service records,
* Version 1.0
* Author(s): Xenia Tkatschow <xenia@us.ibm.com>
@ -21,7 +21,7 @@
#include <asm/cpcmd.h>
#include <asm/debug.h>
#include <asm/ebcdic.h>
#include "../net/iucv.h"
#include <net/iucv/iucv.h>
#include <linux/kmod.h>
#include <linux/cdev.h>
#include <linux/device.h>
@ -60,12 +60,11 @@ struct vmlogrdr_priv_t {
char system_service[8];
char internal_name[8];
char recording_name[8];
u16 pathid;
struct iucv_path *path;
int connection_established;
int iucv_path_severed;
iucv_MessagePending local_interrupt_buffer;
struct iucv_message local_interrupt_buffer;
atomic_t receive_ready;
iucv_handle_t iucv_handle;
int minor_num;
char * buffer;
char * current_position;
@ -97,40 +96,21 @@ static struct file_operations vmlogrdr_fops = {
};
static u8 iucvMagic[16] = {
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
static void vmlogrdr_iucv_path_complete(struct iucv_path *, u8 ipuser[16]);
static void vmlogrdr_iucv_path_severed(struct iucv_path *, u8 ipuser[16]);
static void vmlogrdr_iucv_message_pending(struct iucv_path *,
struct iucv_message *);
static struct iucv_handler vmlogrdr_iucv_handler = {
.path_complete = vmlogrdr_iucv_path_complete,
.path_severed = vmlogrdr_iucv_path_severed,
.message_pending = vmlogrdr_iucv_message_pending,
};
static u8 mask[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
static u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static void
vmlogrdr_iucv_ConnectionComplete(iucv_ConnectionComplete *eib, void *pgm_data);
static void
vmlogrdr_iucv_ConnectionSevered(iucv_ConnectionSevered *eib, void *pgm_data);
static void
vmlogrdr_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data);
static iucv_interrupt_ops_t vmlogrdr_iucvops = {
.ConnectionComplete = vmlogrdr_iucv_ConnectionComplete,
.ConnectionSevered = vmlogrdr_iucv_ConnectionSevered,
.MessagePending = vmlogrdr_iucv_MessagePending,
};
DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue);
DECLARE_WAIT_QUEUE_HEAD(read_wait_queue);
static DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue);
static DECLARE_WAIT_QUEUE_HEAD(read_wait_queue);
/*
* pointer to system service private structure
@ -177,28 +157,29 @@ static struct cdev *vmlogrdr_cdev = NULL;
static int recording_class_AB;
static void
vmlogrdr_iucv_ConnectionComplete (iucv_ConnectionComplete * eib,
void * pgm_data)
static void vmlogrdr_iucv_path_complete(struct iucv_path *path, u8 ipuser[16])
{
struct vmlogrdr_priv_t * logptr = pgm_data;
struct vmlogrdr_priv_t * logptr = path->private;
spin_lock(&logptr->priv_lock);
logptr->connection_established = 1;
spin_unlock(&logptr->priv_lock);
wake_up(&conn_wait_queue);
return;
}
static void
vmlogrdr_iucv_ConnectionSevered (iucv_ConnectionSevered * eib, void * pgm_data)
static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
{
u8 reason = (u8) eib->ipuser[8];
struct vmlogrdr_priv_t * logptr = pgm_data;
struct vmlogrdr_priv_t * logptr = path->private;
u8 reason = (u8) ipuser[8];
printk (KERN_ERR "vmlogrdr: connection severed with"
" reason %i\n", reason);
iucv_path_sever(path, NULL);
kfree(path);
logptr->path = NULL;
spin_lock(&logptr->priv_lock);
logptr->connection_established = 0;
logptr->iucv_path_severed = 1;
@ -210,10 +191,10 @@ vmlogrdr_iucv_ConnectionSevered (iucv_ConnectionSevered * eib, void * pgm_data)
}
static void
vmlogrdr_iucv_MessagePending (iucv_MessagePending * eib, void * pgm_data)
static void vmlogrdr_iucv_message_pending(struct iucv_path *path,
struct iucv_message *msg)
{
struct vmlogrdr_priv_t * logptr = pgm_data;
struct vmlogrdr_priv_t * logptr = path->private;
/*
* This function is the bottom half so it should be quick.
@ -221,15 +202,15 @@ vmlogrdr_iucv_MessagePending (iucv_MessagePending * eib, void * pgm_data)
* the usage count
*/
spin_lock(&logptr->priv_lock);
memcpy(&(logptr->local_interrupt_buffer), eib, sizeof(*eib));
memcpy(&logptr->local_interrupt_buffer, msg, sizeof(*msg));
atomic_inc(&logptr->receive_ready);
spin_unlock(&logptr->priv_lock);
wake_up_interruptible(&read_wait_queue);
}
static int
vmlogrdr_get_recording_class_AB(void) {
static int vmlogrdr_get_recording_class_AB(void)
{
char cp_command[]="QUERY COMMAND RECORDING ";
char cp_response[80];
char *tail;
@ -259,8 +240,9 @@ vmlogrdr_get_recording_class_AB(void) {
}
static int
vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) {
static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
int action, int purge)
{
char cp_command[80];
char cp_response[160];
@ -318,8 +300,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) {
}
static int
vmlogrdr_open (struct inode *inode, struct file *filp)
static int vmlogrdr_open (struct inode *inode, struct file *filp)
{
int dev_num = 0;
struct vmlogrdr_priv_t * logptr = NULL;
@ -329,10 +310,7 @@ vmlogrdr_open (struct inode *inode, struct file *filp)
dev_num = iminor(inode);
if (dev_num > MAXMINOR)
return -ENODEV;
logptr = &sys_ser[dev_num];
if (logptr == NULL)
return -ENODEV;
/*
* only allow for blocking reads to be open
@ -345,52 +323,38 @@ vmlogrdr_open (struct inode *inode, struct file *filp)
if (logptr->dev_in_use) {
spin_unlock_bh(&logptr->priv_lock);
return -EBUSY;
} else {
logptr->dev_in_use = 1;
spin_unlock_bh(&logptr->priv_lock);
}
logptr->dev_in_use = 1;
logptr->connection_established = 0;
logptr->iucv_path_severed = 0;
atomic_set(&logptr->receive_ready, 0);
logptr->buffer_free = 1;
spin_unlock_bh(&logptr->priv_lock);
/* set the file options */
filp->private_data = logptr;
filp->f_op = &vmlogrdr_fops;
/* start recording for this service*/
ret=0;
if (logptr->autorecording)
if (logptr->autorecording) {
ret = vmlogrdr_recording(logptr,1,logptr->autopurge);
if (ret)
printk (KERN_WARNING "vmlogrdr: failed to start "
"recording automatically\n");
/* Register with iucv driver */
logptr->iucv_handle = iucv_register_program(iucvMagic,
logptr->system_service, mask, &vmlogrdr_iucvops,
logptr);
if (logptr->iucv_handle == NULL) {
printk (KERN_ERR "vmlogrdr: failed to register with"
"iucv driver\n");
goto not_registered;
if (ret)
printk (KERN_WARNING "vmlogrdr: failed to start "
"recording automatically\n");
}
/* create connection to the system service */
spin_lock_bh(&logptr->priv_lock);
logptr->connection_established = 0;
logptr->iucv_path_severed = 0;
spin_unlock_bh(&logptr->priv_lock);
connect_rc = iucv_connect (&(logptr->pathid), 10, iucvMagic,
logptr->system_service, iucv_host, 0,
NULL, NULL,
logptr->iucv_handle, NULL);
logptr->path = iucv_path_alloc(10, 0, GFP_KERNEL);
if (!logptr->path)
goto out_dev;
connect_rc = iucv_path_connect(logptr->path, &vmlogrdr_iucv_handler,
logptr->system_service, NULL, NULL,
logptr);
if (connect_rc) {
printk (KERN_ERR "vmlogrdr: iucv connection to %s "
"failed with rc %i \n", logptr->system_service,
connect_rc);
goto not_connected;
goto out_path;
}
/* We've issued the connect and now we must wait for a
@ -399,35 +363,28 @@ vmlogrdr_open (struct inode *inode, struct file *filp)
*/
wait_event(conn_wait_queue, (logptr->connection_established)
|| (logptr->iucv_path_severed));
if (logptr->iucv_path_severed) {
goto not_connected;
}
if (logptr->iucv_path_severed)
goto out_record;
return nonseekable_open(inode, filp);
not_connected:
iucv_unregister_program(logptr->iucv_handle);
logptr->iucv_handle = NULL;
not_registered:
out_record:
if (logptr->autorecording)
vmlogrdr_recording(logptr,0,logptr->autopurge);
out_path:
kfree(logptr->path); /* kfree(NULL) is ok. */
logptr->path = NULL;
out_dev:
logptr->dev_in_use = 0;
return -EIO;
}
static int
vmlogrdr_release (struct inode *inode, struct file *filp)
static int vmlogrdr_release (struct inode *inode, struct file *filp)
{
int ret;
struct vmlogrdr_priv_t * logptr = filp->private_data;
iucv_unregister_program(logptr->iucv_handle);
logptr->iucv_handle = NULL;
if (logptr->autorecording) {
ret = vmlogrdr_recording(logptr,0,logptr->autopurge);
if (ret)
@ -440,8 +397,8 @@ vmlogrdr_release (struct inode *inode, struct file *filp)
}
static int
vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) {
static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv)
{
int rc, *temp;
/* we need to keep track of two data sizes here:
* The number of bytes we need to receive from iucv and
@ -462,8 +419,7 @@ vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) {
* We need to return the total length of the record
* + size of FENCE in the first 4 bytes of the buffer.
*/
iucv_data_count =
priv->local_interrupt_buffer.ln1msg2.ipbfln1f;
iucv_data_count = priv->local_interrupt_buffer.length;
user_data_count = sizeof(int);
temp = (int*)priv->buffer;
*temp= iucv_data_count + sizeof(FENCE);
@ -475,14 +431,10 @@ vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) {
*/
if (iucv_data_count > NET_BUFFER_SIZE)
iucv_data_count = NET_BUFFER_SIZE;
rc = iucv_receive(priv->pathid,
priv->local_interrupt_buffer.ipmsgid,
priv->local_interrupt_buffer.iptrgcls,
buffer,
iucv_data_count,
NULL,
NULL,
&priv->residual_length);
rc = iucv_message_receive(priv->path,
&priv->local_interrupt_buffer,
0, buffer, iucv_data_count,
&priv->residual_length);
spin_unlock_bh(&priv->priv_lock);
/* An rc of 5 indicates that the record was bigger then
* the buffer, which is OK for us. A 9 indicates that the
@ -514,8 +466,8 @@ vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) {
}
static ssize_t
vmlogrdr_read(struct file *filp, char __user *data, size_t count, loff_t * ppos)
static ssize_t vmlogrdr_read(struct file *filp, char __user *data,
size_t count, loff_t * ppos)
{
int rc;
struct vmlogrdr_priv_t * priv = filp->private_data;
@ -547,8 +499,10 @@ vmlogrdr_read(struct file *filp, char __user *data, size_t count, loff_t * ppos)
return count;
}
static ssize_t
vmlogrdr_autopurge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
static ssize_t vmlogrdr_autopurge_store(struct device * dev,
struct device_attribute *attr,
const char * buf, size_t count)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
ssize_t ret = count;
@ -566,8 +520,10 @@ vmlogrdr_autopurge_store(struct device * dev, struct device_attribute *attr, con
}
static ssize_t
vmlogrdr_autopurge_show(struct device *dev, struct device_attribute *attr, char *buf) {
static ssize_t vmlogrdr_autopurge_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
return sprintf(buf, "%u\n", priv->autopurge);
}
@ -577,8 +533,10 @@ static DEVICE_ATTR(autopurge, 0644, vmlogrdr_autopurge_show,
vmlogrdr_autopurge_store);
static ssize_t
vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
static ssize_t vmlogrdr_purge_store(struct device * dev,
struct device_attribute *attr,
const char * buf, size_t count)
{
char cp_command[80];
char cp_response[80];
@ -618,9 +576,10 @@ vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const c
static DEVICE_ATTR(purge, 0200, NULL, vmlogrdr_purge_store);
static ssize_t
vmlogrdr_autorecording_store(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count) {
static ssize_t vmlogrdr_autorecording_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
ssize_t ret = count;
@ -638,8 +597,10 @@ vmlogrdr_autorecording_store(struct device *dev, struct device_attribute *attr,
}
static ssize_t
vmlogrdr_autorecording_show(struct device *dev, struct device_attribute *attr, char *buf) {
static ssize_t vmlogrdr_autorecording_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
return sprintf(buf, "%u\n", priv->autorecording);
}
@ -649,9 +610,10 @@ static DEVICE_ATTR(autorecording, 0644, vmlogrdr_autorecording_show,
vmlogrdr_autorecording_store);
static ssize_t
vmlogrdr_recording_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
static ssize_t vmlogrdr_recording_store(struct device * dev,
struct device_attribute *attr,
const char * buf, size_t count)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
ssize_t ret;
@ -676,8 +638,9 @@ vmlogrdr_recording_store(struct device * dev, struct device_attribute *attr, con
static DEVICE_ATTR(recording, 0200, NULL, vmlogrdr_recording_store);
static ssize_t
vmlogrdr_recording_status_show(struct device_driver *driver, char *buf) {
static ssize_t vmlogrdr_recording_status_show(struct device_driver *driver,
char *buf)
{
char cp_command[] = "QUERY RECORDING ";
int len;
@ -710,52 +673,63 @@ static struct device_driver vmlogrdr_driver = {
};
static int
vmlogrdr_register_driver(void) {
static int vmlogrdr_register_driver(void)
{
int ret;
/* Register with iucv driver */
ret = iucv_register(&vmlogrdr_iucv_handler, 1);
if (ret) {
printk (KERN_ERR "vmlogrdr: failed to register with"
"iucv driver\n");
goto out;
}
ret = driver_register(&vmlogrdr_driver);
if (ret) {
printk(KERN_ERR "vmlogrdr: failed to register driver.\n");
return ret;
goto out_iucv;
}
ret = driver_create_file(&vmlogrdr_driver,
&driver_attr_recording_status);
if (ret) {
printk(KERN_ERR "vmlogrdr: failed to add driver attribute.\n");
goto unregdriver;
goto out_driver;
}
vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr");
if (IS_ERR(vmlogrdr_class)) {
printk(KERN_ERR "vmlogrdr: failed to create class.\n");
ret=PTR_ERR(vmlogrdr_class);
vmlogrdr_class=NULL;
goto unregattr;
ret = PTR_ERR(vmlogrdr_class);
vmlogrdr_class = NULL;
goto out_attr;
}
return 0;
unregattr:
out_attr:
driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status);
unregdriver:
out_driver:
driver_unregister(&vmlogrdr_driver);
out_iucv:
iucv_unregister(&vmlogrdr_iucv_handler, 1);
out:
return ret;
}
static void
vmlogrdr_unregister_driver(void) {
static void vmlogrdr_unregister_driver(void)
{
class_destroy(vmlogrdr_class);
vmlogrdr_class = NULL;
driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status);
driver_unregister(&vmlogrdr_driver);
return;
iucv_unregister(&vmlogrdr_iucv_handler, 1);
}
static int
vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
{
struct device *dev;
int ret;
@ -804,9 +778,10 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
}
static int
vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) {
class_device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num));
static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv)
{
class_device_destroy(vmlogrdr_class,
MKDEV(vmlogrdr_major, priv->minor_num));
if (priv->device != NULL) {
sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group);
device_unregister(priv->device);
@ -816,8 +791,8 @@ vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) {
}
static int
vmlogrdr_register_cdev(dev_t dev) {
static int vmlogrdr_register_cdev(dev_t dev)
{
int rc = 0;
vmlogrdr_cdev = cdev_alloc();
if (!vmlogrdr_cdev) {
@ -837,9 +812,10 @@ vmlogrdr_register_cdev(dev_t dev) {
}
static void
vmlogrdr_cleanup(void) {
static void vmlogrdr_cleanup(void)
{
int i;
if (vmlogrdr_cdev) {
cdev_del(vmlogrdr_cdev);
vmlogrdr_cdev=NULL;
@ -856,8 +832,7 @@ vmlogrdr_cleanup(void) {
}
static int
vmlogrdr_init(void)
static int vmlogrdr_init(void)
{
int rc;
int i;
@ -907,8 +882,7 @@ cleanup:
}
static void
vmlogrdr_exit(void)
static void vmlogrdr_exit(void)
{
vmlogrdr_cleanup();
printk (KERN_INFO "vmlogrdr: driver unloaded\n");

View file

@ -43,7 +43,7 @@ typedef enum {add, free} range_action;
* Function: blacklist_range
* (Un-)blacklist the devices from-to
*/
static inline void
static void
blacklist_range (range_action action, unsigned int from, unsigned int to,
unsigned int ssid)
{
@ -69,7 +69,7 @@ blacklist_range (range_action action, unsigned int from, unsigned int to,
* Get devno/busid from given string.
* Shamelessly grabbed from dasd_devmap.c.
*/
static inline int
static int
blacklist_busid(char **str, int *id0, int *ssid, int *devno)
{
int val, old_style;
@ -123,10 +123,10 @@ confused:
return 1;
}
static inline int
static int
blacklist_parse_parameters (char *str, range_action action)
{
unsigned int from, to, from_id0, to_id0, from_ssid, to_ssid;
int from, to, from_id0, to_id0, from_ssid, to_ssid;
while (*str != 0 && *str != '\n') {
range_action ra = action;
@ -227,7 +227,7 @@ is_blacklisted (int ssid, int devno)
* Function: blacklist_parse_proc_parameters
* parse the stuff which is piped to /proc/cio_ignore
*/
static inline void
static void
blacklist_parse_proc_parameters (char *buf)
{
if (strncmp (buf, "free ", 5) == 0) {

View file

@ -53,7 +53,7 @@ ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer,
static struct bus_type ccwgroup_bus_type;
static inline void
static void
__ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
{
int i;
@ -104,7 +104,7 @@ ccwgroup_release (struct device *dev)
kfree(gdev);
}
static inline int
static int
__ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
{
char str[8];
@ -424,7 +424,7 @@ ccwgroup_probe_ccwdev(struct ccw_device *cdev)
return 0;
}
static inline struct ccwgroup_device *
static struct ccwgroup_device *
__ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev)
{
struct ccwgroup_device *gdev;

View file

@ -93,7 +93,7 @@ chsc_get_sch_desc_irq(struct subchannel *sch, void *page)
u16 sch; /* subchannel */
u8 chpid[8]; /* chpids 0-7 */
u16 fla[8]; /* full link addresses 0-7 */
} *ssd_area;
} __attribute__ ((packed)) *ssd_area;
ssd_area = page;
@ -277,7 +277,7 @@ out_unreg:
return 0;
}
static inline void
static void
s390_set_chpid_offline( __u8 chpid)
{
char dbf_txt[15];
@ -338,7 +338,7 @@ s390_process_res_acc_sch(struct res_acc_data *res_data, struct subchannel *sch)
return 0x80 >> chp;
}
static inline int
static int
s390_process_res_acc_new_sch(struct subchannel_id schid)
{
struct schib schib;
@ -444,7 +444,7 @@ __get_chpid_from_lir(void *data)
u32 andesc[28];
/* incident-specific information */
u32 isinfo[28];
} *lir;
} __attribute__ ((packed)) *lir;
lir = data;
if (!(lir->iq&0x80))
@ -461,154 +461,146 @@ __get_chpid_from_lir(void *data)
return (u16) (lir->indesc[0]&0x000000ff);
}
int
chsc_process_crw(void)
struct chsc_sei_area {
struct chsc_header request;
u32 reserved1;
u32 reserved2;
u32 reserved3;
struct chsc_header response;
u32 reserved4;
u8 flags;
u8 vf; /* validity flags */
u8 rs; /* reporting source */
u8 cc; /* content code */
u16 fla; /* full link address */
u16 rsid; /* reporting source id */
u32 reserved5;
u32 reserved6;
u8 ccdf[4096 - 16 - 24]; /* content-code dependent field */
/* ccdf has to be big enough for a link-incident record */
} __attribute__ ((packed));
static int chsc_process_sei_link_incident(struct chsc_sei_area *sei_area)
{
int chpid;
CIO_CRW_EVENT(4, "chsc: link incident (rs=%02x, rs_id=%04x)\n",
sei_area->rs, sei_area->rsid);
if (sei_area->rs != 4)
return 0;
chpid = __get_chpid_from_lir(sei_area->ccdf);
if (chpid < 0)
CIO_CRW_EVENT(4, "chsc: link incident - invalid LIR\n");
else
s390_set_chpid_offline(chpid);
return 0;
}
static int chsc_process_sei_res_acc(struct chsc_sei_area *sei_area)
{
int chpid, ret;
struct res_acc_data res_data;
struct {
struct chsc_header request;
u32 reserved1;
u32 reserved2;
u32 reserved3;
struct chsc_header response;
u32 reserved4;
u8 flags;
u8 vf; /* validity flags */
u8 rs; /* reporting source */
u8 cc; /* content code */
u16 fla; /* full link address */
u16 rsid; /* reporting source id */
u32 reserved5;
u32 reserved6;
u32 ccdf[96]; /* content-code dependent field */
/* ccdf has to be big enough for a link-incident record */
} *sei_area;
struct device *dev;
int status;
int rc;
CIO_CRW_EVENT(4, "chsc: resource accessibility event (rs=%02x, "
"rs_id=%04x)\n", sei_area->rs, sei_area->rsid);
if (sei_area->rs != 4)
return 0;
/* allocate a new channel path structure, if needed */
status = get_chp_status(sei_area->rsid);
if (status < 0)
new_channel_path(sei_area->rsid);
else if (!status)
return 0;
dev = get_device(&css[0]->chps[sei_area->rsid]->dev);
memset(&res_data, 0, sizeof(struct res_acc_data));
res_data.chp = to_channelpath(dev);
if ((sei_area->vf & 0xc0) != 0) {
res_data.fla = sei_area->fla;
if ((sei_area->vf & 0xc0) == 0xc0)
/* full link address */
res_data.fla_mask = 0xffff;
else
/* link address */
res_data.fla_mask = 0xff00;
}
rc = s390_process_res_acc(&res_data);
put_device(dev);
return rc;
}
static int chsc_process_sei(struct chsc_sei_area *sei_area)
{
int rc;
/* Check if we might have lost some information. */
if (sei_area->flags & 0x40)
CIO_CRW_EVENT(2, "chsc: event overflow\n");
/* which kind of information was stored? */
rc = 0;
switch (sei_area->cc) {
case 1: /* link incident*/
rc = chsc_process_sei_link_incident(sei_area);
break;
case 2: /* i/o resource accessibiliy */
rc = chsc_process_sei_res_acc(sei_area);
break;
default: /* other stuff */
CIO_CRW_EVENT(4, "chsc: unhandled sei content code %d\n",
sei_area->cc);
break;
}
return rc;
}
int chsc_process_crw(void)
{
struct chsc_sei_area *sei_area;
int ret;
int rc;
if (!sei_page)
return 0;
/*
* build the chsc request block for store event information
* and do the call
* This function is only called by the machine check handler thread,
* so we don't need locking for the sei_page.
*/
/* Access to sei_page is serialized through machine check handler
* thread, so no need for locking. */
sei_area = sei_page;
CIO_TRACE_EVENT( 2, "prcss");
ret = 0;
do {
int ccode, status;
struct device *dev;
memset(sei_area, 0, sizeof(*sei_area));
memset(&res_data, 0, sizeof(struct res_acc_data));
sei_area->request.length = 0x0010;
sei_area->request.code = 0x000e;
if (chsc(sei_area))
break;
ccode = chsc(sei_area);
if (ccode > 0)
return 0;
switch (sei_area->response.code) {
/* for debug purposes, check for problems */
case 0x0001:
CIO_CRW_EVENT(4, "chsc_process_crw: event information "
"successfully stored\n");
break; /* everything ok */
case 0x0002:
CIO_CRW_EVENT(2,
"chsc_process_crw: invalid command!\n");
return 0;
case 0x0003:
CIO_CRW_EVENT(2, "chsc_process_crw: error in chsc "
"request block!\n");
return 0;
case 0x0005:
CIO_CRW_EVENT(2, "chsc_process_crw: no event "
"information stored\n");
return 0;
default:
CIO_CRW_EVENT(2, "chsc_process_crw: chsc response %d\n",
if (sei_area->response.code == 0x0001) {
CIO_CRW_EVENT(4, "chsc: sei successful\n");
rc = chsc_process_sei(sei_area);
if (rc)
ret = rc;
} else {
CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n",
sei_area->response.code);
return 0;
}
/* Check if we might have lost some information. */
if (sei_area->flags & 0x40)
CIO_CRW_EVENT(2, "chsc_process_crw: Event information "
"has been lost due to overflow!\n");
if (sei_area->rs != 4) {
CIO_CRW_EVENT(2, "chsc_process_crw: reporting source "
"(%04X) isn't a chpid!\n",
sei_area->rsid);
continue;
}
/* which kind of information was stored? */
switch (sei_area->cc) {
case 1: /* link incident*/
CIO_CRW_EVENT(4, "chsc_process_crw: "
"channel subsystem reports link incident,"
" reporting source is chpid %x\n",
sei_area->rsid);
chpid = __get_chpid_from_lir(sei_area->ccdf);
if (chpid < 0)
CIO_CRW_EVENT(4, "%s: Invalid LIR, skipping\n",
__FUNCTION__);
else
s390_set_chpid_offline(chpid);
break;
case 2: /* i/o resource accessibiliy */
CIO_CRW_EVENT(4, "chsc_process_crw: "
"channel subsystem reports some I/O "
"devices may have become accessible\n");
pr_debug("Data received after sei: \n");
pr_debug("Validity flags: %x\n", sei_area->vf);
/* allocate a new channel path structure, if needed */
status = get_chp_status(sei_area->rsid);
if (status < 0)
new_channel_path(sei_area->rsid);
else if (!status)
break;
dev = get_device(&css[0]->chps[sei_area->rsid]->dev);
res_data.chp = to_channelpath(dev);
pr_debug("chpid: %x", sei_area->rsid);
if ((sei_area->vf & 0xc0) != 0) {
res_data.fla = sei_area->fla;
if ((sei_area->vf & 0xc0) == 0xc0) {
pr_debug(" full link addr: %x",
sei_area->fla);
res_data.fla_mask = 0xffff;
} else {
pr_debug(" link addr: %x",
sei_area->fla);
res_data.fla_mask = 0xff00;
}
}
ret = s390_process_res_acc(&res_data);
pr_debug("\n\n");
put_device(dev);
break;
default: /* other stuff */
CIO_CRW_EVENT(4, "chsc_process_crw: event %d\n",
sei_area->cc);
ret = 0;
break;
}
} while (sei_area->flags & 0x80);
return ret;
}
static inline int
static int
__chp_add_new_sch(struct subchannel_id schid)
{
struct schib schib;
int ret;
if (stsch(schid, &schib))
if (stsch_err(schid, &schib))
/* We're through */
return need_rescan ? -EAGAIN : -ENXIO;
@ -709,7 +701,7 @@ chp_process_crw(int chpid, int on)
return chp_add(chpid);
}
static inline int check_for_io_on_path(struct subchannel *sch, int index)
static int check_for_io_on_path(struct subchannel *sch, int index)
{
int cc;
@ -741,7 +733,7 @@ static void terminate_internal_io(struct subchannel *sch)
sch->driver->termination(&sch->dev);
}
static inline void
static void
__s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
{
int chp, old_lpm;
@ -967,8 +959,8 @@ static struct bin_attribute chp_measurement_attr = {
static void
chsc_remove_chp_cmg_attr(struct channel_path *chp)
{
sysfs_remove_bin_file(&chp->dev.kobj, &chp_measurement_chars_attr);
sysfs_remove_bin_file(&chp->dev.kobj, &chp_measurement_attr);
device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
device_remove_bin_file(&chp->dev, &chp_measurement_attr);
}
static int
@ -976,14 +968,12 @@ chsc_add_chp_cmg_attr(struct channel_path *chp)
{
int ret;
ret = sysfs_create_bin_file(&chp->dev.kobj,
&chp_measurement_chars_attr);
ret = device_create_bin_file(&chp->dev, &chp_measurement_chars_attr);
if (ret)
return ret;
ret = sysfs_create_bin_file(&chp->dev.kobj, &chp_measurement_attr);
ret = device_create_bin_file(&chp->dev, &chp_measurement_attr);
if (ret)
sysfs_remove_bin_file(&chp->dev.kobj,
&chp_measurement_chars_attr);
device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
return ret;
}
@ -1042,7 +1032,7 @@ __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
u32 : 4;
u32 fmt : 4;
u32 : 16;
} *secm_area;
} __attribute__ ((packed)) *secm_area;
int ret, ccode;
secm_area = page;
@ -1253,7 +1243,7 @@ chsc_determine_channel_path_description(int chpid,
struct chsc_header response;
u32 zeroes2;
struct channel_path_desc desc;
} *scpd_area;
} __attribute__ ((packed)) *scpd_area;
scpd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!scpd_area)
@ -1350,7 +1340,7 @@ chsc_get_channel_measurement_chars(struct channel_path *chp)
u32 cmg : 8;
u32 zeroes3;
u32 data[NR_MEASUREMENT_CHARS];
} *scmc_area;
} __attribute__ ((packed)) *scmc_area;
scmc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!scmc_area)
@ -1517,7 +1507,7 @@ chsc_enable_facility(int operation_code)
u32 reserved5:4;
u32 format2:4;
u32 reserved6:24;
} *sda_area;
} __attribute__ ((packed)) *sda_area;
sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA);
if (!sda_area)
@ -1569,7 +1559,7 @@ chsc_determine_css_characteristics(void)
u32 reserved4;
u32 general_char[510];
u32 chsc_char[518];
} *scsc_area;
} __attribute__ ((packed)) *scsc_area;
scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!scsc_area) {

View file

@ -10,17 +10,17 @@
struct chsc_header {
u16 length;
u16 code;
};
} __attribute__ ((packed));
#define NR_MEASUREMENT_CHARS 5
struct cmg_chars {
u32 values[NR_MEASUREMENT_CHARS];
};
} __attribute__ ((packed));
#define NR_MEASUREMENT_ENTRIES 8
struct cmg_entry {
u32 values[NR_MEASUREMENT_ENTRIES];
};
} __attribute__ ((packed));
struct channel_path_desc {
u8 flags;
@ -31,7 +31,7 @@ struct channel_path_desc {
u8 zeroes;
u8 chla;
u8 chpp;
};
} __attribute__ ((packed));
struct channel_path {
int id;
@ -47,6 +47,9 @@ struct channel_path {
extern void s390_process_css( void );
extern void chsc_validate_chpids(struct subchannel *);
extern void chpid_is_actually_online(int);
extern int css_get_ssd_info(struct subchannel *);
extern int chsc_process_crw(void);
extern int chp_process_crw(int, int);
struct css_general_char {
u64 : 41;

View file

@ -122,7 +122,7 @@ cio_get_options (struct subchannel *sch)
* Use tpi to get a pending interrupt, call the interrupt handler and
* return a pointer to the subchannel structure.
*/
static inline int
static int
cio_tpi(void)
{
struct tpi_info *tpi_info;
@ -152,7 +152,7 @@ cio_tpi(void)
return 1;
}
static inline int
static int
cio_start_handle_notoper(struct subchannel *sch, __u8 lpm)
{
char dbf_text[15];
@ -585,7 +585,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
* This device must not be known to Linux. So we simply
* say that there is no device and return ENODEV.
*/
CIO_MSG_EVENT(0, "Blacklisted device detected "
CIO_MSG_EVENT(4, "Blacklisted device detected "
"at devno %04X, subchannel set %x\n",
sch->schib.pmcw.dev, sch->schid.ssid);
err = -ENODEV;
@ -646,7 +646,7 @@ do_IRQ (struct pt_regs *regs)
* Make sure that the i/o interrupt did not "overtake"
* the last HZ timer interrupt.
*/
account_ticks();
account_ticks(S390_lowcore.int_clock);
/*
* Get interrupt information from lowcore
*/
@ -832,7 +832,7 @@ cio_get_console_subchannel(void)
}
#endif
static inline int
static int
__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
{
int retry, cc;
@ -850,7 +850,20 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
return -EBUSY; /* uhm... */
}
static inline int
/* we can't use the normal udelay here, since it enables external interrupts */
static void udelay_reset(unsigned long usecs)
{
uint64_t start_cc, end_cc;
asm volatile ("STCK %0" : "=m" (start_cc));
do {
cpu_relax();
asm volatile ("STCK %0" : "=m" (end_cc));
} while (((end_cc - start_cc)/4096) < usecs);
}
static int
__clear_subchannel_easy(struct subchannel_id schid)
{
int retry;
@ -865,7 +878,7 @@ __clear_subchannel_easy(struct subchannel_id schid)
if (schid_equal(&ti.schid, &schid))
return 0;
}
udelay(100);
udelay_reset(100);
}
return -EBUSY;
}
@ -882,11 +895,11 @@ static int stsch_reset(struct subchannel_id schid, volatile struct schib *addr)
int rc;
pgm_check_occured = 0;
s390_reset_pgm_handler = cio_reset_pgm_check_handler;
s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
rc = stsch(schid, addr);
s390_reset_pgm_handler = NULL;
s390_base_pgm_handler_fn = NULL;
/* The program check handler could have changed pgm_check_occured */
/* The program check handler could have changed pgm_check_occured. */
barrier();
if (pgm_check_occured)
@ -944,7 +957,7 @@ static void css_reset(void)
/* Reset subchannels. */
for_each_subchannel(__shutdown_subchannel_easy, NULL);
/* Reset channel paths. */
s390_reset_mcck_handler = s390_reset_chpids_mcck_handler;
s390_base_mcck_handler_fn = s390_reset_chpids_mcck_handler;
/* Enable channel report machine checks. */
__ctl_set_bit(14, 28);
/* Temporarily reenable machine checks. */
@ -969,7 +982,7 @@ static void css_reset(void)
local_mcck_disable();
/* Disable channel report machine checks. */
__ctl_clear_bit(14, 28);
s390_reset_mcck_handler = NULL;
s390_base_mcck_handler_fn = NULL;
}
static struct reset_call css_reset_call = {

View file

@ -519,8 +519,8 @@ struct cmb {
/* insert a single device into the cmb_area list
* called with cmb_area.lock held from alloc_cmb
*/
static inline int alloc_cmb_single (struct ccw_device *cdev,
struct cmb_data *cmb_data)
static int alloc_cmb_single(struct ccw_device *cdev,
struct cmb_data *cmb_data)
{
struct cmb *cmb;
struct ccw_device_private *node;

View file

@ -30,7 +30,7 @@ struct channel_subsystem *css[__MAX_CSSID + 1];
int css_characteristics_avail = 0;
inline int
int
for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data)
{
struct subchannel_id schid;
@ -108,9 +108,6 @@ css_subchannel_release(struct device *dev)
}
}
extern int css_get_ssd_info(struct subchannel *sch);
int css_sch_device_register(struct subchannel *sch)
{
int ret;
@ -187,7 +184,7 @@ get_subchannel_by_schid(struct subchannel_id schid)
return dev ? to_subchannel(dev) : NULL;
}
static inline int css_get_subchannel_status(struct subchannel *sch)
static int css_get_subchannel_status(struct subchannel *sch)
{
struct schib schib;
@ -299,7 +296,7 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow)
/* Will be done on the slow path. */
return -EAGAIN;
}
if (stsch(schid, &schib) || !schib.pmcw.dnv) {
if (stsch_err(schid, &schib) || !schib.pmcw.dnv) {
/* Unusable - ignore. */
return 0;
}
@ -417,7 +414,7 @@ static void reprobe_all(struct work_struct *unused)
need_reprobe);
}
DECLARE_WORK(css_reprobe_work, reprobe_all);
static DECLARE_WORK(css_reprobe_work, reprobe_all);
/* Schedule reprobing of all unregistered subchannels. */
void css_schedule_reprobe(void)
@ -578,7 +575,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store);
static inline int __init setup_css(int nr)
static int __init setup_css(int nr)
{
u32 tod_high;
int ret;

View file

@ -143,6 +143,8 @@ extern void css_sch_device_unregister(struct subchannel *);
extern struct subchannel * get_subchannel_by_schid(struct subchannel_id);
extern int css_init_done;
extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
extern int css_process_crw(int, int);
extern void css_reiterate_subchannels(void);
#define __MAX_SUBCHANNEL 65535
#define __MAX_SSID 3

View file

@ -138,7 +138,6 @@ struct bus_type ccw_bus_type;
static int io_subchannel_probe (struct subchannel *);
static int io_subchannel_remove (struct subchannel *);
void io_subchannel_irq (struct device *);
static int io_subchannel_notify(struct device *, int);
static void io_subchannel_verify(struct device *);
static void io_subchannel_ioterm(struct device *);
@ -235,11 +234,8 @@ chpids_show (struct device * dev, struct device_attribute *attr, char * buf)
ssize_t ret = 0;
int chp;
if (ssd)
for (chp = 0; chp < 8; chp++)
ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]);
else
ret += sprintf (buf, "n/a");
for (chp = 0; chp < 8; chp++)
ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]);
ret += sprintf (buf+ret, "\n");
return min((ssize_t)PAGE_SIZE, ret);
}
@ -552,13 +548,13 @@ static struct attribute_group ccwdev_attr_group = {
.attrs = ccwdev_attrs,
};
static inline int
static int
device_add_files (struct device *dev)
{
return sysfs_create_group(&dev->kobj, &ccwdev_attr_group);
}
static inline void
static void
device_remove_files(struct device *dev)
{
sysfs_remove_group(&dev->kobj, &ccwdev_attr_group);

View file

@ -74,6 +74,7 @@ extern struct workqueue_struct *ccw_device_notify_work;
extern wait_queue_head_t ccw_device_init_wq;
extern atomic_t ccw_device_init_count;
void io_subchannel_irq (struct device *pdev);
void io_subchannel_recog_done(struct ccw_device *cdev);
int ccw_device_cancel_halt_clear(struct ccw_device *);
@ -118,6 +119,7 @@ int ccw_device_stlck(struct ccw_device *);
/* qdio needs this. */
void ccw_device_set_timeout(struct ccw_device *, int);
extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *);
extern struct bus_type ccw_bus_type;
/* Channel measurement facility related */
void retry_set_schib(struct ccw_device *cdev);

View file

@ -206,7 +206,7 @@ ccw_device_handle_oper(struct ccw_device *cdev)
* been varied online on the SE so we have to find out by magic (i. e. driving
* the channel subsystem to device selection and updating our path masks).
*/
static inline void
static void
__recover_lost_chpids(struct subchannel *sch, int old_lpm)
{
int mask, i;
@ -387,7 +387,7 @@ ccw_device_done(struct ccw_device *cdev, int state)
put_device (&cdev->dev);
}
static inline int cmp_pgid(struct pgid *p1, struct pgid *p2)
static int cmp_pgid(struct pgid *p1, struct pgid *p2)
{
char *c1;
char *c2;
@ -842,6 +842,8 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event)
call_handler_unsol:
if (cdev->handler)
cdev->handler (cdev, 0, irb);
if (cdev->private->flags.doverify)
ccw_device_online_verify(cdev, 0);
return;
}
/* Accumulate status and find out if a basic sense is needed. */
@ -892,7 +894,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event)
/*
* Got an interrupt for a basic sense.
*/
void
static void
ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
{
struct irb *irb;

View file

@ -302,7 +302,7 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
wake_up(&cdev->private->wait_q);
}
static inline int
static int
__ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, __u8 lpm)
{
int ret;

View file

@ -25,7 +25,7 @@
* Check for any kind of channel or interface control check but don't
* issue the message for the console device
*/
static inline void
static void
ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
{
if (!(irb->scsw.cstat & (SCHN_STAT_CHN_DATA_CHK |
@ -72,7 +72,7 @@ ccw_device_path_notoper(struct ccw_device *cdev)
/*
* Copy valid bits from the extended control word to device irb.
*/
static inline void
static void
ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb)
{
/*
@ -94,7 +94,7 @@ ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb)
/*
* Check if extended status word is valid.
*/
static inline int
static int
ccw_device_accumulate_esw_valid(struct irb *irb)
{
if (!irb->scsw.eswf && irb->scsw.stctl == SCSW_STCTL_STATUS_PEND)
@ -109,7 +109,7 @@ ccw_device_accumulate_esw_valid(struct irb *irb)
/*
* Copy valid bits from the extended status word to device irb.
*/
static inline void
static void
ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb)
{
struct irb *cdev_irb;

View file

@ -66,7 +66,6 @@ MODULE_LICENSE("GPL");
/******************** HERE WE GO ***********************************/
static const char version[] = "QDIO base support version 2";
extern struct bus_type ccw_bus_type;
static int qdio_performance_stats = 0;
static int proc_perf_file_registration;
@ -138,7 +137,7 @@ qdio_release_q(struct qdio_q *q)
}
/*check ccq */
static inline int
static int
qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
{
char dbf_text[15];
@ -153,7 +152,7 @@ qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
return -EIO;
}
/* EQBS: extract buffer states */
static inline int
static int
qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
unsigned int *start, unsigned int *cnt)
{
@ -188,7 +187,7 @@ again:
}
/* SQBS: set buffer states */
static inline int
static int
qdio_do_sqbs(struct qdio_q *q, unsigned char state,
unsigned int *start, unsigned int *cnt)
{
@ -315,7 +314,7 @@ __do_siga_output(struct qdio_q *q, unsigned int *busy_bit)
* returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns
* an access exception
*/
static inline int
static int
qdio_siga_output(struct qdio_q *q)
{
int cc;
@ -349,7 +348,7 @@ qdio_siga_output(struct qdio_q *q)
return cc;
}
static inline int
static int
qdio_siga_input(struct qdio_q *q)
{
int cc;
@ -421,7 +420,7 @@ tiqdio_sched_tl(void)
tasklet_hi_schedule(&tiqdio_tasklet);
}
static inline void
static void
qdio_mark_tiq(struct qdio_q *q)
{
unsigned long flags;
@ -471,7 +470,7 @@ qdio_mark_q(struct qdio_q *q)
tasklet_schedule(&q->tasklet);
}
static inline int
static int
qdio_stop_polling(struct qdio_q *q)
{
#ifdef QDIO_USE_PROCESSING_STATE
@ -525,7 +524,7 @@ qdio_stop_polling(struct qdio_q *q)
* sophisticated locking outside of unmark_q, so that we don't need to
* disable the interrupts :-)
*/
static inline void
static void
qdio_unmark_q(struct qdio_q *q)
{
unsigned long flags;
@ -691,7 +690,7 @@ qdio_qebsm_get_inbound_buffer_frontier(struct qdio_q *q)
return q->first_to_check;
}
static inline int
static int
qdio_get_outbound_buffer_frontier(struct qdio_q *q)
{
struct qdio_irq *irq;
@ -774,7 +773,7 @@ out:
}
/* all buffers are processed */
static inline int
static int
qdio_is_outbound_q_done(struct qdio_q *q)
{
int no_used;
@ -796,7 +795,7 @@ qdio_is_outbound_q_done(struct qdio_q *q)
return (no_used==0);
}
static inline int
static int
qdio_has_outbound_q_moved(struct qdio_q *q)
{
int i;
@ -816,7 +815,7 @@ qdio_has_outbound_q_moved(struct qdio_q *q)
}
}
static inline void
static void
qdio_kick_outbound_q(struct qdio_q *q)
{
int result;
@ -905,7 +904,7 @@ qdio_kick_outbound_q(struct qdio_q *q)
}
}
static inline void
static void
qdio_kick_outbound_handler(struct qdio_q *q)
{
int start, end, real_end, count;
@ -942,7 +941,7 @@ qdio_kick_outbound_handler(struct qdio_q *q)
q->error_status_flags=0;
}
static inline void
static void
__qdio_outbound_processing(struct qdio_q *q)
{
int siga_attempts;
@ -1002,7 +1001,7 @@ qdio_outbound_processing(struct qdio_q *q)
/************************* INBOUND ROUTINES *******************************/
static inline int
static int
qdio_get_inbound_buffer_frontier(struct qdio_q *q)
{
struct qdio_irq *irq;
@ -1133,7 +1132,7 @@ out:
return q->first_to_check;
}
static inline int
static int
qdio_has_inbound_q_moved(struct qdio_q *q)
{
int i;
@ -1167,7 +1166,7 @@ qdio_has_inbound_q_moved(struct qdio_q *q)
}
/* means, no more buffers to be filled */
static inline int
static int
tiqdio_is_inbound_q_done(struct qdio_q *q)
{
int no_used;
@ -1228,7 +1227,7 @@ tiqdio_is_inbound_q_done(struct qdio_q *q)
return 0;
}
static inline int
static int
qdio_is_inbound_q_done(struct qdio_q *q)
{
int no_used;
@ -1296,7 +1295,7 @@ qdio_is_inbound_q_done(struct qdio_q *q)
}
}
static inline void
static void
qdio_kick_inbound_handler(struct qdio_q *q)
{
int count, start, end, real_end, i;
@ -1343,7 +1342,7 @@ qdio_kick_inbound_handler(struct qdio_q *q)
}
}
static inline void
static void
__tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set)
{
struct qdio_irq *irq_ptr;
@ -1442,7 +1441,7 @@ tiqdio_inbound_processing(struct qdio_q *q)
__tiqdio_inbound_processing(q, atomic_read(&spare_indicator_usecount));
}
static inline void
static void
__qdio_inbound_processing(struct qdio_q *q)
{
int q_laps=0;
@ -1493,7 +1492,7 @@ qdio_inbound_processing(struct qdio_q *q)
/************************* MAIN ROUTINES *******************************/
#ifdef QDIO_USE_PROCESSING_STATE
static inline int
static int
tiqdio_reset_processing_state(struct qdio_q *q, int q_laps)
{
if (!q) {
@ -1545,7 +1544,7 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps)
}
#endif /* QDIO_USE_PROCESSING_STATE */
static inline void
static void
tiqdio_inbound_checks(void)
{
struct qdio_q *q;
@ -1949,7 +1948,7 @@ qdio_set_state(struct qdio_irq *irq_ptr, enum qdio_irq_states state)
mb();
}
static inline void
static void
qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
{
char dbf_text[15];
@ -1966,7 +1965,7 @@ qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
}
static inline void
static void
qdio_handle_pci(struct qdio_irq *irq_ptr)
{
int i;
@ -2002,7 +2001,7 @@ qdio_handle_pci(struct qdio_irq *irq_ptr)
static void qdio_establish_handle_irq(struct ccw_device*, int, int);
static inline void
static void
qdio_handle_activate_check(struct ccw_device *cdev, unsigned long intparm,
int cstat, int dstat)
{
@ -2229,7 +2228,7 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
return cc;
}
static inline void
static void
qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac,
unsigned long token)
{
@ -2740,7 +2739,7 @@ qdio_free(struct ccw_device *cdev)
return 0;
}
static inline void
static void
qdio_allocate_do_dbf(struct qdio_initialize *init_data)
{
char dbf_text[20]; /* if a printf printed out more than 8 chars */
@ -2773,7 +2772,7 @@ qdio_allocate_do_dbf(struct qdio_initialize *init_data)
QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*));
}
static inline void
static void
qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt)
{
irq_ptr->input_qs[i]->is_iqdio_q = iqfmt;
@ -2792,7 +2791,7 @@ qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt)
irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY;
}
static inline void
static void
qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i,
int j, int iqfmt)
{
@ -2813,7 +2812,7 @@ qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i,
}
static inline void
static void
qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr)
{
int i;
@ -2839,7 +2838,7 @@ qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr)
}
}
static inline void
static void
qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr)
{
int i;
@ -2865,7 +2864,7 @@ qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr)
}
}
static inline int
static int
qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat,
int dstat)
{
@ -3014,7 +3013,7 @@ qdio_allocate(struct qdio_initialize *init_data)
return 0;
}
int qdio_fill_irq(struct qdio_initialize *init_data)
static int qdio_fill_irq(struct qdio_initialize *init_data)
{
int i;
char dbf_text[15];
@ -3367,7 +3366,7 @@ qdio_activate(struct ccw_device *cdev, int flags)
}
/* buffers filled forwards again to make Rick happy */
static inline void
static void
qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx,
unsigned int count, struct qdio_buffer *buffers)
{
@ -3386,7 +3385,7 @@ qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx,
}
}
static inline void
static void
qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx,
unsigned int count, struct qdio_buffer *buffers)
{
@ -3407,7 +3406,7 @@ qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx,
}
}
static inline void
static void
do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
unsigned int qidx, unsigned int count,
struct qdio_buffer *buffers)
@ -3443,7 +3442,7 @@ do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
qdio_mark_q(q);
}
static inline void
static void
do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
unsigned int qidx, unsigned int count,
struct qdio_buffer *buffers)

View file

@ -465,7 +465,7 @@ static int ap_device_probe(struct device *dev)
* Flush all requests from the request/pending queue of an AP device.
* @ap_dev: pointer to the AP device.
*/
static inline void __ap_flush_queue(struct ap_device *ap_dev)
static void __ap_flush_queue(struct ap_device *ap_dev)
{
struct ap_message *ap_msg, *next;
@ -587,7 +587,7 @@ static struct bus_attribute *const ap_bus_attrs[] = {
/**
* Pick one of the 16 ap domains.
*/
static inline int ap_select_domain(void)
static int ap_select_domain(void)
{
int queue_depth, device_type, count, max_count, best_domain;
int rc, i, j;
@ -825,7 +825,7 @@ static inline void ap_schedule_poll_timer(void)
* required, bit 2^1 is set if the poll timer needs to get armed
* Returns 0 if the device is still present, -ENODEV if not.
*/
static inline int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
{
struct ap_queue_status status;
struct ap_message *ap_msg;
@ -872,7 +872,7 @@ static inline int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
* required, bit 2^1 is set if the poll timer needs to get armed
* Returns 0 if the device is still present, -ENODEV if not.
*/
static inline int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
{
struct ap_queue_status status;
struct ap_message *ap_msg;

View file

@ -791,7 +791,7 @@ static long trans_xcRB32(struct file *filp, unsigned int cmd,
return rc;
}
long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd,
static long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
if (cmd == ICARSAMODEXPO)
@ -833,8 +833,8 @@ static struct miscdevice zcrypt_misc_device = {
*/
static struct proc_dir_entry *zcrypt_entry;
static inline int sprintcl(unsigned char *outaddr, unsigned char *addr,
unsigned int len)
static int sprintcl(unsigned char *outaddr, unsigned char *addr,
unsigned int len)
{
int hl, i;
@ -845,8 +845,8 @@ static inline int sprintcl(unsigned char *outaddr, unsigned char *addr,
return hl;
}
static inline int sprintrw(unsigned char *outaddr, unsigned char *addr,
unsigned int len)
static int sprintrw(unsigned char *outaddr, unsigned char *addr,
unsigned int len)
{
int hl, inl, c, cx;
@ -865,8 +865,8 @@ static inline int sprintrw(unsigned char *outaddr, unsigned char *addr,
return hl;
}
static inline int sprinthx(unsigned char *title, unsigned char *outaddr,
unsigned char *addr, unsigned int len)
static int sprinthx(unsigned char *title, unsigned char *outaddr,
unsigned char *addr, unsigned int len)
{
int hl, inl, r, rx;
@ -885,8 +885,8 @@ static inline int sprinthx(unsigned char *title, unsigned char *outaddr,
return hl;
}
static inline int sprinthx4(unsigned char *title, unsigned char *outaddr,
unsigned int *array, unsigned int len)
static int sprinthx4(unsigned char *title, unsigned char *outaddr,
unsigned int *array, unsigned int len)
{
int hl, r;
@ -943,7 +943,7 @@ static int zcrypt_status_read(char *resp_buff, char **start, off_t offset,
zcrypt_qdepth_mask(workarea);
len += sprinthx("Waiting work element counts",
resp_buff+len, workarea, AP_DEVICES);
zcrypt_perdev_reqcnt((unsigned int *) workarea);
zcrypt_perdev_reqcnt((int *) workarea);
len += sprinthx4("Per-device successfully completed request counts",
resp_buff+len,(unsigned int *) workarea, AP_DEVICES);
*eof = 1;

View file

@ -191,10 +191,10 @@ static int ICACRT_msg_to_type4CRT_msg(struct zcrypt_device *zdev,
*
* Returns 0 on success or -EFAULT.
*/
static inline int convert_type84(struct zcrypt_device *zdev,
struct ap_message *reply,
char __user *outputdata,
unsigned int outputdatalength)
static int convert_type84(struct zcrypt_device *zdev,
struct ap_message *reply,
char __user *outputdata,
unsigned int outputdatalength)
{
struct type84_hdr *t84h = reply->message;
char *data;

View file

@ -709,7 +709,8 @@ out_free:
* PCIXCC/CEX2C device to the request distributor
* @xcRB: pointer to the send_cprb request buffer
*/
long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, struct ica_xcRB *xcRB)
static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
struct ica_xcRB *xcRB)
{
struct ap_message ap_msg;
struct response_type resp_type = {

View file

@ -22,13 +22,6 @@ config CTC
available. This option is also available as a module which will be
called ctc.ko. If you do not know what it is, it's safe to say "Y".
config IUCV
tristate "IUCV support (VM only)"
help
Select this option if you want to use inter-user communication
under VM or VIF. If unsure, say "Y" to enable a fast communication
link between VM guests.
config NETIUCV
tristate "IUCV network device support (VM only)"
depends on IUCV && NETDEVICES

View file

@ -4,7 +4,6 @@
ctc-objs := ctcmain.o ctcdbug.o
obj-$(CONFIG_IUCV) += iucv.o
obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o

View file

@ -121,7 +121,7 @@ MODULE_LICENSE("GPL");
#define DEBUG
#endif
char debug_buffer[255];
static char debug_buffer[255];
/**
* Debug Facility Stuff
*/
@ -223,16 +223,14 @@ static void claw_timer ( struct chbk * p_ch );
/* Functions */
static int add_claw_reads(struct net_device *dev,
struct ccwbk* p_first, struct ccwbk* p_last);
static void inline ccw_check_return_code (struct ccw_device *cdev,
int return_code);
static void inline ccw_check_unit_check (struct chbk * p_ch,
unsigned char sense );
static void ccw_check_return_code (struct ccw_device *cdev, int return_code);
static void ccw_check_unit_check (struct chbk * p_ch, unsigned char sense );
static int find_link(struct net_device *dev, char *host_name, char *ws_name );
static int claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid);
static int init_ccw_bk(struct net_device *dev);
static void probe_error( struct ccwgroup_device *cgdev);
static struct net_device_stats *claw_stats(struct net_device *dev);
static int inline pages_to_order_of_mag(int num_of_pages);
static int pages_to_order_of_mag(int num_of_pages);
static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr);
#ifdef DEBUG
static void dumpit (char *buf, int len);
@ -1310,7 +1308,7 @@ claw_timer ( struct chbk * p_ch )
* of magnitude get_free_pages() has an upper order of 9 *
*--------------------------------------------------------------------*/
static int inline
static int
pages_to_order_of_mag(int num_of_pages)
{
int order_of_mag=1; /* assume 2 pages */
@ -1482,7 +1480,7 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
* *
*-------------------------------------------------------------------*/
static void inline
static void
ccw_check_return_code(struct ccw_device *cdev, int return_code)
{
#ifdef FUNCTRACE
@ -1529,7 +1527,7 @@ ccw_check_return_code(struct ccw_device *cdev, int return_code)
* ccw_check_unit_check *
*--------------------------------------------------------------------*/
static void inline
static void
ccw_check_unit_check(struct chbk * p_ch, unsigned char sense )
{
struct net_device *dev = p_ch->ndev;

View file

@ -369,7 +369,7 @@ ctc_dump_skb(struct sk_buff *skb, int offset)
* @param ch The channel where this skb has been received.
* @param pskb The received skb.
*/
static __inline__ void
static void
ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
{
struct net_device *dev = ch->netdev;
@ -512,7 +512,7 @@ ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
* @param ch The channel, the error belongs to.
* @param return_code The error code to inspect.
*/
static void inline
static void
ccw_check_return_code(struct channel *ch, int return_code, char *msg)
{
DBF_TEXT(trace, 5, __FUNCTION__);
@ -547,7 +547,7 @@ ccw_check_return_code(struct channel *ch, int return_code, char *msg)
* @param ch The channel, the sense code belongs to.
* @param sense The sense code to inspect.
*/
static void inline
static void
ccw_unit_check(struct channel *ch, unsigned char sense)
{
DBF_TEXT(trace, 5, __FUNCTION__);
@ -603,7 +603,7 @@ ctc_purge_skb_queue(struct sk_buff_head *q)
}
}
static __inline__ int
static int
ctc_checkalloc_buffer(struct channel *ch, int warn)
{
DBF_TEXT(trace, 5, __FUNCTION__);

View file

@ -57,7 +57,7 @@ static struct ccw_device_id cu3088_ids[] = {
static struct ccw_driver cu3088_driver;
struct device *cu3088_root_dev;
static struct device *cu3088_root_dev;
static ssize_t
group_write(struct device_driver *drv, const char *buf, size_t count)

File diff suppressed because it is too large Load diff

View file

@ -1,849 +0,0 @@
/*
* drivers/s390/net/iucv.h
* IUCV base support.
*
* S390 version
* Copyright (C) 2000 IBM Corporation
* Author(s):Alan Altmark (Alan_Altmark@us.ibm.com)
* Xenia Tkatschow (xenia@us.ibm.com)
*
*
* Functionality:
* To explore any of the IUCV functions, one must first register
* their program using iucv_register_program(). Once your program has
* successfully completed a register, it can exploit the other functions.
* For furthur reference on all IUCV functionality, refer to the
* CP Programming Services book, also available on the web
* thru www.ibm.com/s390/vm/pubs, manual # SC24-5760
*
* Definition of Return Codes
* -All positive return codes including zero are reflected back
* from CP except for iucv_register_program. The definition of each
* return code can be found in CP Programming Services book.
* Also available on the web thru www.ibm.com/s390/vm/pubs, manual # SC24-5760
* - Return Code of:
* (-EINVAL) Invalid value
* (-ENOMEM) storage allocation failed
* pgmask defined in iucv_register_program will be set depending on input
* paramters.
*
*/
#include <linux/types.h>
#include <asm/debug.h>
/**
* Debug Facility stuff
*/
#define IUCV_DBF_SETUP_NAME "iucv_setup"
#define IUCV_DBF_SETUP_LEN 32
#define IUCV_DBF_SETUP_PAGES 2
#define IUCV_DBF_SETUP_NR_AREAS 1
#define IUCV_DBF_SETUP_LEVEL 3
#define IUCV_DBF_DATA_NAME "iucv_data"
#define IUCV_DBF_DATA_LEN 128
#define IUCV_DBF_DATA_PAGES 2
#define IUCV_DBF_DATA_NR_AREAS 1
#define IUCV_DBF_DATA_LEVEL 2
#define IUCV_DBF_TRACE_NAME "iucv_trace"
#define IUCV_DBF_TRACE_LEN 16
#define IUCV_DBF_TRACE_PAGES 4
#define IUCV_DBF_TRACE_NR_AREAS 1
#define IUCV_DBF_TRACE_LEVEL 3
#define IUCV_DBF_TEXT(name,level,text) \
do { \
debug_text_event(iucv_dbf_##name,level,text); \
} while (0)
#define IUCV_DBF_HEX(name,level,addr,len) \
do { \
debug_event(iucv_dbf_##name,level,(void*)(addr),len); \
} while (0)
DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf);
#define IUCV_DBF_TEXT_(name,level,text...) \
do { \
char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \
sprintf(iucv_dbf_txt_buf, text); \
debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \
put_cpu_var(iucv_dbf_txt_buf); \
} while (0)
#define IUCV_DBF_SPRINTF(name,level,text...) \
do { \
debug_sprintf_event(iucv_dbf_trace, level, ##text ); \
debug_sprintf_event(iucv_dbf_trace, level, text ); \
} while (0)
/**
* some more debug stuff
*/
#define IUCV_HEXDUMP16(importance,header,ptr) \
PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
"%02x %02x %02x %02x %02x %02x %02x %02x\n", \
*(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \
*(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \
*(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \
*(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \
*(((char*)ptr)+12),*(((char*)ptr)+13), \
*(((char*)ptr)+14),*(((char*)ptr)+15)); \
PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
"%02x %02x %02x %02x %02x %02x %02x %02x\n", \
*(((char*)ptr)+16),*(((char*)ptr)+17), \
*(((char*)ptr)+18),*(((char*)ptr)+19), \
*(((char*)ptr)+20),*(((char*)ptr)+21), \
*(((char*)ptr)+22),*(((char*)ptr)+23), \
*(((char*)ptr)+24),*(((char*)ptr)+25), \
*(((char*)ptr)+26),*(((char*)ptr)+27), \
*(((char*)ptr)+28),*(((char*)ptr)+29), \
*(((char*)ptr)+30),*(((char*)ptr)+31));
static inline void
iucv_hex_dump(unsigned char *buf, size_t len)
{
size_t i;
for (i = 0; i < len; i++) {
if (i && !(i % 16))
printk("\n");
printk("%02x ", *(buf + i));
}
printk("\n");
}
/**
* end of debug stuff
*/
#define uchar unsigned char
#define ushort unsigned short
#define ulong unsigned long
#define iucv_handle_t void *
/* flags1:
* All flags are defined in the field IPFLAGS1 of each function
* and can be found in CP Programming Services.
* IPLOCAL - Indicates the connect can only be satisfied on the
* local system
* IPPRTY - Indicates a priority message
* IPQUSCE - Indicates you do not want to receive messages on a
* path until an iucv_resume is issued
* IPRMDATA - Indicates that the message is in the parameter list
*/
#define IPLOCAL 0x01
#define IPPRTY 0x20
#define IPQUSCE 0x40
#define IPRMDATA 0x80
/* flags1_out:
* All flags are defined in the output field of IPFLAGS1 for each function
* and can be found in CP Programming Services.
* IPNORPY - Specifies this is a one-way message and no reply is expected.
* IPPRTY - Indicates a priority message is permitted. Defined in flags1.
*/
#define IPNORPY 0x10
#define Nonpriority_MessagePendingInterruptsFlag 0x80
#define Priority_MessagePendingInterruptsFlag 0x40
#define Nonpriority_MessageCompletionInterruptsFlag 0x20
#define Priority_MessageCompletionInterruptsFlag 0x10
#define IUCVControlInterruptsFlag 0x08
#define AllInterrupts 0xf8
/*
* Mapping of external interrupt buffers should be used with the corresponding
* interrupt types.
* Names: iucv_ConnectionPending -> connection pending
* iucv_ConnectionComplete -> connection complete
* iucv_ConnectionSevered -> connection severed
* iucv_ConnectionQuiesced -> connection quiesced
* iucv_ConnectionResumed -> connection resumed
* iucv_MessagePending -> message pending
* iucv_MessageComplete -> message complete
*/
typedef struct {
u16 ippathid;
uchar ipflags1;
uchar iptype;
u16 ipmsglim;
u16 res1;
uchar ipvmid[8];
uchar ipuser[16];
u32 res3;
uchar ippollfg;
uchar res4[3];
} iucv_ConnectionPending;
typedef struct {
u16 ippathid;
uchar ipflags1;
uchar iptype;
u16 ipmsglim;
u16 res1;
uchar res2[8];
uchar ipuser[16];
u32 res3;
uchar ippollfg;
uchar res4[3];
} iucv_ConnectionComplete;
typedef struct {
u16 ippathid;
uchar res1;
uchar iptype;
u32 res2;
uchar res3[8];
uchar ipuser[16];
u32 res4;
uchar ippollfg;
uchar res5[3];
} iucv_ConnectionSevered;
typedef struct {
u16 ippathid;
uchar res1;
uchar iptype;
u32 res2;
uchar res3[8];
uchar ipuser[16];
u32 res4;
uchar ippollfg;
uchar res5[3];
} iucv_ConnectionQuiesced;
typedef struct {
u16 ippathid;
uchar res1;
uchar iptype;
u32 res2;
uchar res3[8];
uchar ipuser[16];
u32 res4;
uchar ippollfg;
uchar res5[3];
} iucv_ConnectionResumed;
typedef struct {
u16 ippathid;
uchar ipflags1;
uchar iptype;
u32 ipmsgid;
u32 iptrgcls;
union u2 {
u32 iprmmsg1_u32;
uchar iprmmsg1[4];
} ln1msg1;
union u1 {
u32 ipbfln1f;
uchar iprmmsg2[4];
} ln1msg2;
u32 res1[3];
u32 ipbfln2f;
uchar ippollfg;
uchar res2[3];
} iucv_MessagePending;
typedef struct {
u16 ippathid;
uchar ipflags1;
uchar iptype;
u32 ipmsgid;
u32 ipaudit;
uchar iprmmsg[8];
u32 ipsrccls;
u32 ipmsgtag;
u32 res;
u32 ipbfln2f;
uchar ippollfg;
uchar res2[3];
} iucv_MessageComplete;
/*
* iucv_interrupt_ops_t: Is a vector of functions that handle
* IUCV interrupts.
* Parameter list:
* eib - is a pointer to a 40-byte area described
* with one of the structures above.
* pgm_data - this data is strictly for the
* interrupt handler that is passed by
* the application. This may be an address
* or token.
*/
typedef struct {
void (*ConnectionPending) (iucv_ConnectionPending * eib,
void *pgm_data);
void (*ConnectionComplete) (iucv_ConnectionComplete * eib,
void *pgm_data);
void (*ConnectionSevered) (iucv_ConnectionSevered * eib,
void *pgm_data);
void (*ConnectionQuiesced) (iucv_ConnectionQuiesced * eib,
void *pgm_data);
void (*ConnectionResumed) (iucv_ConnectionResumed * eib,
void *pgm_data);
void (*MessagePending) (iucv_MessagePending * eib, void *pgm_data);
void (*MessageComplete) (iucv_MessageComplete * eib, void *pgm_data);
} iucv_interrupt_ops_t;
/*
*iucv_array_t : Defines buffer array.
* Inside the array may be 31- bit addresses and 31-bit lengths.
*/
typedef struct {
u32 address;
u32 length;
} iucv_array_t __attribute__ ((aligned (8)));
extern struct bus_type iucv_bus;
extern struct device *iucv_root;
/* -prototypes- */
/*
* Name: iucv_register_program
* Purpose: Registers an application with IUCV
* Input: prmname - user identification
* userid - machine identification
* pgmmask - indicates which bits in the prmname and userid combined will be
* used to determine who is given control
* ops - address of vector of interrupt handlers
* pgm_data- application data passed to interrupt handlers
* Output: NA
* Return: address of handler
* (0) - Error occurred, registration not completed.
* NOTE: Exact cause of failure will be recorded in syslog.
*/
iucv_handle_t iucv_register_program (uchar pgmname[16],
uchar userid[8],
uchar pgmmask[24],
iucv_interrupt_ops_t * ops,
void *pgm_data);
/*
* Name: iucv_unregister_program
* Purpose: Unregister application with IUCV
* Input: address of handler
* Output: NA
* Return: (0) - Normal return
* (-EINVAL) - Internal error, wild pointer
*/
int iucv_unregister_program (iucv_handle_t handle);
/*
* Name: iucv_accept
* Purpose: This function is issued after the user receives a Connection Pending external
* interrupt and now wishes to complete the IUCV communication path.
* Input: pathid - u16 , Path identification number
* msglim_reqstd - u16, The number of outstanding messages requested.
* user_data - uchar[16], Data specified by the iucv_connect function.
* flags1 - int, Contains options for this path.
* -IPPRTY - 0x20- Specifies if you want to send priority message.
* -IPRMDATA - 0x80, Specifies whether your program can handle a message
* in the parameter list.
* -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being
* established.
* handle - iucv_handle_t, Address of handler.
* pgm_data - void *, Application data passed to interrupt handlers.
* flags1_out - int * Contains information about the path
* - IPPRTY - 0x20, Indicates you may send priority messages.
* msglim - *u16, Number of outstanding messages.
* Output: return code from CP IUCV call.
*/
int iucv_accept (u16 pathid,
u16 msglim_reqstd,
uchar user_data[16],
int flags1,
iucv_handle_t handle,
void *pgm_data, int *flags1_out, u16 * msglim);
/*
* Name: iucv_connect
* Purpose: This function establishes an IUCV path. Although the connect may complete
* successfully, you are not able to use the path until you receive an IUCV
* Connection Complete external interrupt.
* Input: pathid - u16 *, Path identification number
* msglim_reqstd - u16, Number of outstanding messages requested
* user_data - uchar[16], 16-byte user data
* userid - uchar[8], User identification
* system_name - uchar[8], 8-byte identifying the system name
* flags1 - int, Contains options for this path.
* -IPPRTY - 0x20, Specifies if you want to send priority message.
* -IPRMDATA - 0x80, Specifies whether your program can handle a message
* in the parameter list.
* -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being
* established.
* -IPLOCAL - 0X01, Allows an application to force the partner to be on
* the local system. If local is specified then target class cannot be
* specified.
* flags1_out - int * Contains information about the path
* - IPPRTY - 0x20, Indicates you may send priority messages.
* msglim - * u16, Number of outstanding messages
* handle - iucv_handle_t, Address of handler
* pgm_data - void *, Application data passed to interrupt handlers
* Output: return code from CP IUCV call
* rc - return code from iucv_declare_buffer
* -EINVAL - Invalid handle passed by application
* -EINVAL - Pathid address is NULL
* add_pathid_result - Return code from internal function add_pathid
*/
int
iucv_connect (u16 * pathid,
u16 msglim_reqstd,
uchar user_data[16],
uchar userid[8],
uchar system_name[8],
int flags1,
int *flags1_out,
u16 * msglim, iucv_handle_t handle, void *pgm_data);
/*
* Name: iucv_purge
* Purpose: This function cancels a message that you have sent.
* Input: pathid - Path identification number.
* msgid - Specifies the message ID of the message to be purged.
* srccls - Specifies the source message class.
* Output: audit - Contains information about asynchronous error
* that may have affected the normal completion
* of this message.
* Return: Return code from CP IUCV call.
*/
int iucv_purge (u16 pathid, u32 msgid, u32 srccls, __u32 *audit);
/*
* Name: iucv_query_maxconn
* Purpose: This function determines the maximum number of communication paths you
* may establish.
* Return: maxconn - ulong, Maximum number of connection the virtual machine may
* establish.
*/
ulong iucv_query_maxconn (void);
/*
* Name: iucv_query_bufsize
* Purpose: This function determines how large an external interrupt
* buffer IUCV requires to store information.
* Return: bufsize - ulong, Size of external interrupt buffer.
*/
ulong iucv_query_bufsize (void);
/*
* Name: iucv_quiesce
* Purpose: This function temporarily suspends incoming messages on an
* IUCV path. You can later reactivate the path by invoking
* the iucv_resume function.
* Input: pathid - Path identification number
* user_data - 16-bytes of user data
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_quiesce (u16 pathid, uchar user_data[16]);
/*
* Name: iucv_receive
* Purpose: This function receives messages that are being sent to you
* over established paths. Data will be returned in buffer for length of
* buflen.
* Input:
* pathid - Path identification number.
* buffer - Address of buffer to receive.
* buflen - Length of buffer to receive.
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* Output:
* flags1_out: int *, Contains information about this path.
* IPNORPY - 0x10 Specifies this is a one-way message and no reply is
* expected.
* IPPRTY - 0x20 Specifies if you want to send priority message.
* IPRMDATA - 0x80 specifies the data is contained in the parameter list
* residual_buffer - address of buffer updated by the number
* of bytes you have received.
* residual_length -
* Contains one of the following values, if the receive buffer is:
* The same length as the message, this field is zero.
* Longer than the message, this field contains the number of
* bytes remaining in the buffer.
* Shorter than the message, this field contains the residual
* count (that is, the number of bytes remaining in the
* message that does not fit into the buffer. In this
* case b2f0_result = 5.
* Return: Return code from CP IUCV call.
* (-EINVAL) - buffer address is pointing to NULL
*/
int iucv_receive (u16 pathid,
u32 msgid,
u32 trgcls,
void *buffer,
ulong buflen,
int *flags1_out,
ulong * residual_buffer, ulong * residual_length);
/*
* Name: iucv_receive_array
* Purpose: This function receives messages that are being sent to you
* over established paths. Data will be returned in first buffer for
* length of first buffer.
* Input: pathid - Path identification number.
* msgid - specifies the message ID.
* trgcls - Specifies target class.
* buffer - Address of array of buffers.
* buflen - Total length of buffers.
* Output:
* flags1_out: int *, Contains information about this path.
* IPNORPY - 0x10 Specifies this is a one-way message and no reply is
* expected.
* IPPRTY - 0x20 Specifies if you want to send priority message.
* IPRMDATA - 0x80 specifies the data is contained in the parameter list
* residual_buffer - address points to the current list entry IUCV
* is working on.
* residual_length -
* Contains one of the following values, if the receive buffer is:
* The same length as the message, this field is zero.
* Longer than the message, this field contains the number of
* bytes remaining in the buffer.
* Shorter than the message, this field contains the residual
* count (that is, the number of bytes remaining in the
* message that does not fit into the buffer. In this
* case b2f0_result = 5.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_receive_array (u16 pathid,
u32 msgid,
u32 trgcls,
iucv_array_t * buffer,
ulong buflen,
int *flags1_out,
ulong * residual_buffer, ulong * residual_length);
/*
* Name: iucv_reject
* Purpose: The reject function refuses a specified message. Between the
* time you are notified of a message and the time that you
* complete the message, the message may be rejected.
* Input: pathid - Path identification number.
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_reject (u16 pathid, u32 msgid, u32 trgcls);
/*
* Name: iucv_reply
* Purpose: This function responds to the two-way messages that you
* receive. You must identify completely the message to
* which you wish to reply. ie, pathid, msgid, and trgcls.
* Input: pathid - Path identification number.
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* flags1 - Option for path.
* IPPRTY- 0x20, Specifies if you want to send priority message.
* buffer - Address of reply buffer.
* buflen - Length of reply buffer.
* Output: residual_buffer - Address of buffer updated by the number
* of bytes you have moved.
* residual_length - Contains one of the following values:
* If the answer buffer is the same length as the reply, this field
* contains zero.
* If the answer buffer is longer than the reply, this field contains
* the number of bytes remaining in the buffer.
* If the answer buffer is shorter than the reply, this field contains
* a residual count (that is, the number of bytes remianing in the
* reply that does not fit into the buffer. In this
* case b2f0_result = 5.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_reply (u16 pathid,
u32 msgid,
u32 trgcls,
int flags1,
void *buffer, ulong buflen, ulong * residual_buffer,
ulong * residual_length);
/*
* Name: iucv_reply_array
* Purpose: This function responds to the two-way messages that you
* receive. You must identify completely the message to
* which you wish to reply. ie, pathid, msgid, and trgcls.
* The array identifies a list of addresses and lengths of
* discontiguous buffers that contains the reply data.
* Input: pathid - Path identification number
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* flags1 - Option for path.
* IPPRTY- 0x20, Specifies if you want to send priority message.
* buffer - Address of array of reply buffers.
* buflen - Total length of reply buffers.
* Output: residual_buffer - Address of buffer which IUCV is currently working on.
* residual_length - Contains one of the following values:
* If the answer buffer is the same length as the reply, this field
* contains zero.
* If the answer buffer is longer than the reply, this field contains
* the number of bytes remaining in the buffer.
* If the answer buffer is shorter than the reply, this field contains
* a residual count (that is, the number of bytes remianing in the
* reply that does not fit into the buffer. In this
* case b2f0_result = 5.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_reply_array (u16 pathid,
u32 msgid,
u32 trgcls,
int flags1,
iucv_array_t * buffer,
ulong buflen, ulong * residual_address,
ulong * residual_length);
/*
* Name: iucv_reply_prmmsg
* Purpose: This function responds to the two-way messages that you
* receive. You must identify completely the message to
* which you wish to reply. ie, pathid, msgid, and trgcls.
* Prmmsg signifies the data is moved into the
* parameter list.
* Input: pathid - Path identification number.
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* prmmsg - 8-bytes of data to be placed into the parameter.
* list.
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_reply_prmmsg (u16 pathid,
u32 msgid, u32 trgcls, int flags1, uchar prmmsg[8]);
/*
* Name: iucv_resume
* Purpose: This function restores communications over a quiesced path
* Input: pathid - Path identification number.
* user_data - 16-bytes of user data.
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_resume (u16 pathid, uchar user_data[16]);
/*
* Name: iucv_send
* Purpose: This function transmits data to another application.
* Data to be transmitted is in a buffer and this is a
* one-way message and the receiver will not reply to the
* message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* buffer - Address of send buffer.
* buflen - Length of send buffer.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_send (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls, u32 msgtag, int flags1, void *buffer, ulong buflen);
/*
* Name: iucv_send_array
* Purpose: This function transmits data to another application.
* The contents of buffer is the address of the array of
* addresses and lengths of discontiguous buffers that hold
* the message text. This is a one-way message and the
* receiver will not reply to the message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated witht the message.
* flags1 - Option for path.
* IPPRTY- specifies if you want to send priority message.
* buffer - Address of array of send buffers.
* buflen - Total length of send buffers.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_send_array (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
int flags1, iucv_array_t * buffer, ulong buflen);
/*
* Name: iucv_send_prmmsg
* Purpose: This function transmits data to another application.
* Prmmsg specifies that the 8-bytes of data are to be moved
* into the parameter list. This is a one-way message and the
* receiver will not reply to the message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 specifies if you want to send priority message.
* prmmsg - 8-bytes of data to be placed into parameter list.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
*/
int iucv_send_prmmsg (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls, u32 msgtag, int flags1, uchar prmmsg[8]);
/*
* Name: iucv_send2way
* Purpose: This function transmits data to another application.
* Data to be transmitted is in a buffer. The receiver
* of the send is expected to reply to the message and
* a buffer is provided into which IUCV moves the reply
* to this message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* buffer - Address of send buffer.
* buflen - Length of send buffer.
* ansbuf - Address of buffer into which IUCV moves the reply of
* this message.
* anslen - Address of length of buffer.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer or ansbuf address is NULL.
*/
int iucv_send2way (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
int flags1,
void *buffer, ulong buflen, void *ansbuf, ulong anslen);
/*
* Name: iucv_send2way_array
* Purpose: This function transmits data to another application.
* The contents of buffer is the address of the array of
* addresses and lengths of discontiguous buffers that hold
* the message text. The receiver of the send is expected to
* reply to the message and a buffer is provided into which
* IUCV moves the reply to this message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* buffer - Sddress of array of send buffers.
* buflen - Total length of send buffers.
* ansbuf - Address of array of buffer into which IUCV moves the reply
* of this message.
* anslen - Address of length reply buffers.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_send2way_array (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
int flags1,
iucv_array_t * buffer,
ulong buflen, iucv_array_t * ansbuf, ulong anslen);
/*
* Name: iucv_send2way_prmmsg
* Purpose: This function transmits data to another application.
* Prmmsg specifies that the 8-bytes of data are to be moved
* into the parameter list. This is a two-way message and the
* receiver of the message is expected to reply. A buffer
* is provided into which IUCV moves the reply to this
* message.
* Input: pathid - Rath identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* prmmsg - 8-bytes of data to be placed in parameter list.
* ansbuf - Address of buffer into which IUCV moves the reply of
* this message.
* anslen - Address of length of buffer.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_send2way_prmmsg (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
ulong flags1,
uchar prmmsg[8], void *ansbuf, ulong anslen);
/*
* Name: iucv_send2way_prmmsg_array
* Purpose: This function transmits data to another application.
* Prmmsg specifies that the 8-bytes of data are to be moved
* into the parameter list. This is a two-way message and the
* receiver of the message is expected to reply. A buffer
* is provided into which IUCV moves the reply to this
* message. The contents of ansbuf is the address of the
* array of addresses and lengths of discontiguous buffers
* that contain the reply.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 specifies if you want to send priority message.
* prmmsg - 8-bytes of data to be placed into the parameter list.
* ansbuf - Address of array of buffer into which IUCV moves the reply
* of this message.
* anslen - Address of length of reply buffers.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Ansbuf address is NULL.
*/
int iucv_send2way_prmmsg_array (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
int flags1,
uchar prmmsg[8],
iucv_array_t * ansbuf, ulong anslen);
/*
* Name: iucv_setmask
* Purpose: This function enables or disables the following IUCV
* external interruptions: Nonpriority and priority message
* interrupts, nonpriority and priority reply interrupts.
* Input: SetMaskFlag - options for interrupts
* 0x80 - Nonpriority_MessagePendingInterruptsFlag
* 0x40 - Priority_MessagePendingInterruptsFlag
* 0x20 - Nonpriority_MessageCompletionInterruptsFlag
* 0x10 - Priority_MessageCompletionInterruptsFlag
* 0x08 - IUCVControlInterruptsFlag
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_setmask (int SetMaskFlag);
/*
* Name: iucv_sever
* Purpose: This function terminates an IUCV path.
* Input: pathid - Path identification number.
* user_data - 16-bytes of user data.
* Output: NA
* Return: Return code from CP IUCV call.
* (-EINVAL) - Interal error, wild pointer.
*/
int iucv_sever (u16 pathid, uchar user_data[16]);

View file

@ -828,7 +828,7 @@ lcs_notify_lancmd_waiters(struct lcs_card *card, struct lcs_cmd *cmd)
/**
* Emit buffer of a lan comand.
*/
void
static void
lcs_lancmd_timeout(unsigned long data)
{
struct lcs_reply *reply, *list_reply, *r;
@ -1360,7 +1360,7 @@ lcs_get_problem(struct ccw_device *cdev, struct irb *irb)
return 0;
}
void
static void
lcs_schedule_recovery(struct lcs_card *card)
{
LCS_DBF_TEXT(2, trace, "startrec");
@ -1990,7 +1990,7 @@ lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char
}
DEVICE_ATTR(lancmd_timeout, 0644, lcs_timeout_show, lcs_timeout_store);
static DEVICE_ATTR(lancmd_timeout, 0644, lcs_timeout_show, lcs_timeout_store);
static ssize_t
lcs_dev_recover_store(struct device *dev, struct device_attribute *attr,

File diff suppressed because it is too large Load diff

View file

@ -49,7 +49,7 @@ qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
return buffers_needed;
}
static inline void
static void
qeth_eddp_free_context(struct qeth_eddp_context *ctx)
{
int i;
@ -91,7 +91,7 @@ qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
}
}
static inline int
static int
qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
struct qeth_eddp_context *ctx)
{
@ -196,7 +196,7 @@ out:
return flush_cnt;
}
static inline void
static void
qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
struct qeth_eddp_data *eddp, int data_len)
{
@ -256,7 +256,7 @@ qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
ctx->offset += eddp->thl;
}
static inline void
static void
qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
__wsum *hcsum)
{
@ -302,7 +302,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
}
}
static inline void
static void
qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
struct qeth_eddp_data *eddp, int data_len,
__wsum hcsum)
@ -349,7 +349,7 @@ qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum);
}
static inline __wsum
static __wsum
qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
{
__wsum phcsum; /* pseudo header checksum */
@ -363,7 +363,7 @@ qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
return csum_partial((u8 *)&eddp->th, eddp->thl, phcsum);
}
static inline __wsum
static __wsum
qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len)
{
__be32 proto;
@ -381,7 +381,7 @@ qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len)
return phcsum;
}
static inline struct qeth_eddp_data *
static struct qeth_eddp_data *
qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl)
{
struct qeth_eddp_data *eddp;
@ -399,7 +399,7 @@ qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl)
return eddp;
}
static inline void
static void
__qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
struct qeth_eddp_data *eddp)
{
@ -464,7 +464,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
}
}
static inline int
static int
qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
struct sk_buff *skb, struct qeth_hdr *qhdr)
{
@ -505,7 +505,7 @@ qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
return 0;
}
static inline void
static void
qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
int hdr_len)
{
@ -529,7 +529,7 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
(skb_shinfo(skb)->gso_segs + 1);
}
static inline struct qeth_eddp_context *
static struct qeth_eddp_context *
qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb,
int hdr_len)
{
@ -581,7 +581,7 @@ qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb,
return ctx;
}
static inline struct qeth_eddp_context *
static struct qeth_eddp_context *
qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *qhdr)
{
@ -625,5 +625,3 @@ qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb,
}
return NULL;
}

View file

@ -651,7 +651,7 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
return 0;
}
static inline int
static int
__qeth_address_exists_in_list(struct list_head *list, struct qeth_ipaddr *addr,
int same_type)
{
@ -795,7 +795,7 @@ qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
return rc;
}
static inline void
static void
__qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
{
struct qeth_ipaddr *addr, *tmp;
@ -882,7 +882,7 @@ static void qeth_layer2_add_multicast(struct qeth_card *);
static void qeth_add_multicast_ipv6(struct qeth_card *);
#endif
static inline int
static int
qeth_set_thread_start_bit(struct qeth_card *card, unsigned long thread)
{
unsigned long flags;
@ -920,7 +920,7 @@ qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
wake_up(&card->wait_q);
}
static inline int
static int
__qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
{
unsigned long flags;
@ -1764,9 +1764,9 @@ out:
qeth_release_buffer(channel,iob);
}
static inline void
static void
qeth_prepare_control_data(struct qeth_card *card, int len,
struct qeth_cmd_buffer *iob)
struct qeth_cmd_buffer *iob)
{
qeth_setup_ccw(&card->write,iob->data,len);
iob->callback = qeth_release_buffer;
@ -2160,7 +2160,7 @@ qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
return 0;
}
static inline struct sk_buff *
static struct sk_buff *
qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
{
struct sk_buff* skb;
@ -2179,7 +2179,7 @@ qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
return skb;
}
static inline struct sk_buff *
static struct sk_buff *
qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
struct qdio_buffer_element **__element, int *__offset,
struct qeth_hdr **hdr)
@ -2264,7 +2264,7 @@ no_mem:
return NULL;
}
static inline __be16
static __be16
qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct qeth_card *card;
@ -2297,7 +2297,7 @@ qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
return htons(ETH_P_802_2);
}
static inline void
static void
qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr)
{
@ -2351,7 +2351,7 @@ qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
fake_llc->ethertype = ETH_P_IP;
}
static inline void
static void
qeth_rebuild_skb_fake_ll_eth(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr)
{
@ -2420,7 +2420,7 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
}
static inline __u16
static __u16
qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr)
{
@ -2476,7 +2476,7 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
return vlan_id;
}
static inline void
static void
qeth_process_inbound_buffer(struct qeth_card *card,
struct qeth_qdio_buffer *buf, int index)
{
@ -2528,7 +2528,7 @@ qeth_process_inbound_buffer(struct qeth_card *card,
}
}
static inline struct qeth_buffer_pool_entry *
static struct qeth_buffer_pool_entry *
qeth_get_buffer_pool_entry(struct qeth_card *card)
{
struct qeth_buffer_pool_entry *entry;
@ -2543,7 +2543,7 @@ qeth_get_buffer_pool_entry(struct qeth_card *card)
return NULL;
}
static inline void
static void
qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
{
struct qeth_buffer_pool_entry *pool_entry;
@ -2570,7 +2570,7 @@ qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
buf->state = QETH_QDIO_BUF_EMPTY;
}
static inline void
static void
qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
struct qeth_qdio_out_buffer *buf)
{
@ -2595,7 +2595,7 @@ qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
}
static inline void
static void
qeth_queue_input_buffer(struct qeth_card *card, int index)
{
struct qeth_qdio_q *queue = card->qdio.in_q;
@ -2699,7 +2699,7 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
card->perf_stats.inbound_start_time;
}
static inline int
static int
qeth_handle_send_error(struct qeth_card *card,
struct qeth_qdio_out_buffer *buffer,
unsigned int qdio_err, unsigned int siga_err)
@ -2821,7 +2821,7 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
* Switched to packing state if the number of used buffers on a queue
* reaches a certain limit.
*/
static inline void
static void
qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue)
{
if (!queue->do_pack) {
@ -2842,7 +2842,7 @@ qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue)
* In that case 1 is returned to inform the caller. If no buffer
* has to be flushed, zero is returned.
*/
static inline int
static int
qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
{
struct qeth_qdio_out_buffer *buffer;
@ -2877,7 +2877,7 @@ qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
* Checks if there is a packing buffer and prepares it to be flushed.
* In that case returns 1, otherwise zero.
*/
static inline int
static int
qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue)
{
struct qeth_qdio_out_buffer *buffer;
@ -2894,7 +2894,7 @@ qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue)
return 0;
}
static inline void
static void
qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
{
int index;
@ -3594,7 +3594,7 @@ qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
}
}
static inline int
static int
qeth_send_packet(struct qeth_card *, struct sk_buff *);
static int
@ -3759,7 +3759,7 @@ qeth_stop(struct net_device *dev)
return 0;
}
static inline int
static int
qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
{
int cast_type = RTN_UNSPEC;
@ -3806,7 +3806,7 @@ qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
return cast_type;
}
static inline int
static int
qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
int ipv, int cast_type)
{
@ -3853,7 +3853,7 @@ qeth_get_ip_version(struct sk_buff *skb)
}
}
static inline struct qeth_hdr *
static struct qeth_hdr *
__qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv)
{
#ifdef CONFIG_QETH_VLAN
@ -3882,14 +3882,14 @@ __qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv)
qeth_push_skb(card, skb, sizeof(struct qeth_hdr)));
}
static inline void
static void
__qeth_free_new_skb(struct sk_buff *orig_skb, struct sk_buff *new_skb)
{
if (orig_skb != new_skb)
dev_kfree_skb_any(new_skb);
}
static inline struct sk_buff *
static struct sk_buff *
qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr **hdr, int ipv)
{
@ -3940,7 +3940,7 @@ qeth_get_qeth_hdr_flags6(int cast_type)
return ct | QETH_CAST_UNICAST;
}
static inline void
static void
qeth_layer2_get_packet_type(struct qeth_card *card, struct qeth_hdr *hdr,
struct sk_buff *skb)
{
@ -3977,7 +3977,7 @@ qeth_layer2_get_packet_type(struct qeth_card *card, struct qeth_hdr *hdr,
}
}
static inline void
static void
qeth_layer2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
struct sk_buff *skb, int cast_type)
{
@ -4068,7 +4068,7 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
}
}
static inline void
static void
__qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer,
int is_tso, int *next_element_to_fill)
{
@ -4112,7 +4112,7 @@ __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer,
*next_element_to_fill = element;
}
static inline int
static int
qeth_fill_buffer(struct qeth_qdio_out_q *queue,
struct qeth_qdio_out_buffer *buf,
struct sk_buff *skb)
@ -4171,7 +4171,7 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue,
return flush_cnt;
}
static inline int
static int
qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue,
struct sk_buff *skb, struct qeth_hdr *hdr,
int elements_needed,
@ -4222,7 +4222,7 @@ out:
return -EBUSY;
}
static inline int
static int
qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
struct sk_buff *skb, struct qeth_hdr *hdr,
int elements_needed, struct qeth_eddp_context *ctx)
@ -4328,7 +4328,7 @@ out:
return rc;
}
static inline int
static int
qeth_get_elements_no(struct qeth_card *card, void *hdr,
struct sk_buff *skb, int elems)
{
@ -4349,7 +4349,7 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr,
}
static inline int
static int
qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
{
int ipv = 0;
@ -4536,7 +4536,7 @@ qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
}
static inline const char *
static const char *
qeth_arp_get_error_cause(int *rc)
{
switch (*rc) {
@ -4597,7 +4597,7 @@ qeth_arp_set_no_entries(struct qeth_card *card, int no_entries)
return rc;
}
static inline void
static void
qeth_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo,
struct qeth_arp_query_data *qdata,
int entry_size, int uentry_size)
@ -5214,7 +5214,7 @@ qeth_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
spin_unlock_irqrestore(&card->vlanlock, flags);
}
static inline void
static void
qeth_free_vlan_buffer(struct qeth_card *card, struct qeth_qdio_out_buffer *buf,
unsigned short vid)
{
@ -5625,7 +5625,7 @@ qeth_delete_mc_addresses(struct qeth_card *card)
spin_unlock_irqrestore(&card->ip_lock, flags);
}
static inline void
static void
qeth_add_mc(struct qeth_card *card, struct in_device *in4_dev)
{
struct qeth_ipaddr *ipm;
@ -5711,7 +5711,7 @@ qeth_layer2_add_multicast(struct qeth_card *card)
}
#ifdef CONFIG_QETH_IPV6
static inline void
static void
qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
{
struct qeth_ipaddr *ipm;
@ -6022,7 +6022,7 @@ qeth_send_setdelmc(struct qeth_card *card, struct qeth_ipaddr *addr, int ipacmd)
return rc;
}
static inline void
static void
qeth_fill_netmask(u8 *netmask, unsigned int len)
{
int i,j;
@ -6626,7 +6626,7 @@ qeth_send_setadp_mode(struct qeth_card *card, __u32 command, __u32 mode)
return rc;
}
static inline int
static int
qeth_setadapter_hstr(struct qeth_card *card)
{
int rc;
@ -6889,7 +6889,7 @@ qeth_send_simple_setassparms(struct qeth_card *card,
return rc;
}
static inline int
static int
qeth_start_ipa_arp_processing(struct qeth_card *card)
{
int rc;
@ -7529,7 +7529,7 @@ qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
wake_up(&card->wait_q);
}
static inline int
static int
qeth_threads_running(struct qeth_card *card, unsigned long threads)
{
unsigned long flags;
@ -8118,7 +8118,7 @@ qeth_del_ipato_entry(struct qeth_card *card, enum qeth_prot_versions proto,
spin_unlock_irqrestore(&card->ip_lock, flags);
}
static inline void
static void
qeth_convert_addr_to_bits(u8 *addr, u8 *bits, int len)
{
int i, j;

View file

@ -328,7 +328,7 @@ qeth_dev_bufcnt_store(struct device *dev, struct device_attribute *attr, const c
static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
qeth_dev_bufcnt_store);
static inline ssize_t
static ssize_t
qeth_dev_route_show(struct qeth_card *card, struct qeth_routing_info *route,
char *buf)
{
@ -368,7 +368,7 @@ qeth_dev_route4_show(struct device *dev, struct device_attribute *attr, char *bu
return qeth_dev_route_show(card, &card->options.route4, buf);
}
static inline ssize_t
static ssize_t
qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route,
enum qeth_prot_versions prot, const char *buf, size_t count)
{
@ -998,7 +998,7 @@ struct device_attribute dev_attr_##_id = { \
.store = _store, \
};
int
static int
qeth_check_layer2(struct qeth_card *card)
{
if (card->options.layer2)
@ -1100,7 +1100,7 @@ static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
qeth_dev_ipato_invert4_show,
qeth_dev_ipato_invert4_store);
static inline ssize_t
static ssize_t
qeth_dev_ipato_add_show(char *buf, struct qeth_card *card,
enum qeth_prot_versions proto)
{
@ -1146,7 +1146,7 @@ qeth_dev_ipato_add4_show(struct device *dev, struct device_attribute *attr, char
return qeth_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
}
static inline int
static int
qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
u8 *addr, int *mask_bits)
{
@ -1178,7 +1178,7 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
return 0;
}
static inline ssize_t
static ssize_t
qeth_dev_ipato_add_store(const char *buf, size_t count,
struct qeth_card *card, enum qeth_prot_versions proto)
{
@ -1223,7 +1223,7 @@ static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
qeth_dev_ipato_add4_show,
qeth_dev_ipato_add4_store);
static inline ssize_t
static ssize_t
qeth_dev_ipato_del_store(const char *buf, size_t count,
struct qeth_card *card, enum qeth_prot_versions proto)
{
@ -1361,7 +1361,7 @@ static struct attribute_group qeth_device_ipato_group = {
.attrs = (struct attribute **)qeth_ipato_device_attrs,
};
static inline ssize_t
static ssize_t
qeth_dev_vipa_add_show(char *buf, struct qeth_card *card,
enum qeth_prot_versions proto)
{
@ -1407,7 +1407,7 @@ qeth_dev_vipa_add4_show(struct device *dev, struct device_attribute *attr, char
return qeth_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
}
static inline int
static int
qeth_parse_vipae(const char* buf, enum qeth_prot_versions proto,
u8 *addr)
{
@ -1418,7 +1418,7 @@ qeth_parse_vipae(const char* buf, enum qeth_prot_versions proto,
return 0;
}
static inline ssize_t
static ssize_t
qeth_dev_vipa_add_store(const char *buf, size_t count,
struct qeth_card *card, enum qeth_prot_versions proto)
{
@ -1451,7 +1451,7 @@ static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
qeth_dev_vipa_add4_show,
qeth_dev_vipa_add4_store);
static inline ssize_t
static ssize_t
qeth_dev_vipa_del_store(const char *buf, size_t count,
struct qeth_card *card, enum qeth_prot_versions proto)
{
@ -1542,7 +1542,7 @@ static struct attribute_group qeth_device_vipa_group = {
.attrs = (struct attribute **)qeth_vipa_device_attrs,
};
static inline ssize_t
static ssize_t
qeth_dev_rxip_add_show(char *buf, struct qeth_card *card,
enum qeth_prot_versions proto)
{
@ -1588,7 +1588,7 @@ qeth_dev_rxip_add4_show(struct device *dev, struct device_attribute *attr, char
return qeth_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
}
static inline int
static int
qeth_parse_rxipe(const char* buf, enum qeth_prot_versions proto,
u8 *addr)
{
@ -1599,7 +1599,7 @@ qeth_parse_rxipe(const char* buf, enum qeth_prot_versions proto,
return 0;
}
static inline ssize_t
static ssize_t
qeth_dev_rxip_add_store(const char *buf, size_t count,
struct qeth_card *card, enum qeth_prot_versions proto)
{
@ -1632,7 +1632,7 @@ static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
qeth_dev_rxip_add4_show,
qeth_dev_rxip_add4_store);
static inline ssize_t
static ssize_t
qeth_dev_rxip_del_store(const char *buf, size_t count,
struct qeth_card *card, enum qeth_prot_versions proto)
{

View file

@ -1,7 +1,7 @@
/*
* IUCV special message driver
*
* Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* This program is free software; you can redistribute it and/or modify
@ -23,10 +23,10 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <net/iucv/iucv.h>
#include <asm/cpcmd.h>
#include <asm/ebcdic.h>
#include "iucv.h"
#include "smsgiucv.h"
struct smsg_callback {
struct list_head list;
@ -39,38 +39,46 @@ MODULE_AUTHOR
("(C) 2003 IBM Corporation by Martin Schwidefsky ([email protected])");
MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver");
static iucv_handle_t smsg_handle;
static unsigned short smsg_pathid;
static struct iucv_path *smsg_path;
static DEFINE_SPINLOCK(smsg_list_lock);
static struct list_head smsg_list = LIST_HEAD_INIT(smsg_list);
static void
smsg_connection_complete(iucv_ConnectionComplete *eib, void *pgm_data)
static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]);
static void smsg_message_pending(struct iucv_path *, struct iucv_message *);
static struct iucv_handler smsg_handler = {
.path_pending = smsg_path_pending,
.message_pending = smsg_message_pending,
};
static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8],
u8 ipuser[16])
{
if (strncmp(ipvmid, "*MSG ", sizeof(ipvmid)) != 0)
return -EINVAL;
/* Path pending from *MSG. */
return iucv_path_accept(path, &smsg_handler, "SMSGIUCV ", NULL);
}
static void
smsg_message_pending(iucv_MessagePending *eib, void *pgm_data)
static void smsg_message_pending(struct iucv_path *path,
struct iucv_message *msg)
{
struct smsg_callback *cb;
unsigned char *msg;
unsigned char *buffer;
unsigned char sender[9];
unsigned short len;
int rc, i;
len = eib->ln1msg2.ipbfln1f;
msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA);
if (!msg) {
iucv_reject(eib->ippathid, eib->ipmsgid, eib->iptrgcls);
buffer = kmalloc(msg->length + 1, GFP_ATOMIC | GFP_DMA);
if (!buffer) {
iucv_message_reject(path, msg);
return;
}
rc = iucv_receive(eib->ippathid, eib->ipmsgid, eib->iptrgcls,
msg, len, NULL, NULL, NULL);
rc = iucv_message_receive(path, msg, 0, buffer, msg->length, NULL);
if (rc == 0) {
msg[len] = 0;
EBCASC(msg, len);
memcpy(sender, msg, 8);
buffer[msg->length] = 0;
EBCASC(buffer, msg->length);
memcpy(sender, buffer, 8);
sender[8] = 0;
/* Remove trailing whitespace from the sender name. */
for (i = 7; i >= 0; i--) {
@ -80,27 +88,17 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data)
}
spin_lock(&smsg_list_lock);
list_for_each_entry(cb, &smsg_list, list)
if (strncmp(msg + 8, cb->prefix, cb->len) == 0) {
cb->callback(sender, msg + 8);
if (strncmp(buffer + 8, cb->prefix, cb->len) == 0) {
cb->callback(sender, buffer + 8);
break;
}
spin_unlock(&smsg_list_lock);
}
kfree(msg);
kfree(buffer);
}
static iucv_interrupt_ops_t smsg_ops = {
.ConnectionComplete = smsg_connection_complete,
.MessagePending = smsg_message_pending,
};
static struct device_driver smsg_driver = {
.name = "SMSGIUCV",
.bus = &iucv_bus,
};
int
smsg_register_callback(char *prefix, void (*callback)(char *from, char *str))
int smsg_register_callback(char *prefix,
void (*callback)(char *from, char *str))
{
struct smsg_callback *cb;
@ -110,18 +108,18 @@ smsg_register_callback(char *prefix, void (*callback)(char *from, char *str))
cb->prefix = prefix;
cb->len = strlen(prefix);
cb->callback = callback;
spin_lock(&smsg_list_lock);
spin_lock_bh(&smsg_list_lock);
list_add_tail(&cb->list, &smsg_list);
spin_unlock(&smsg_list_lock);
spin_unlock_bh(&smsg_list_lock);
return 0;
}
void
smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str))
void smsg_unregister_callback(char *prefix,
void (*callback)(char *from, char *str))
{
struct smsg_callback *cb, *tmp;
spin_lock(&smsg_list_lock);
spin_lock_bh(&smsg_list_lock);
cb = NULL;
list_for_each_entry(tmp, &smsg_list, list)
if (tmp->callback == callback &&
@ -130,55 +128,58 @@ smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str))
list_del(&cb->list);
break;
}
spin_unlock(&smsg_list_lock);
spin_unlock_bh(&smsg_list_lock);
kfree(cb);
}
static void __exit
smsg_exit(void)
static struct device_driver smsg_driver = {
.name = "SMSGIUCV",
.bus = &iucv_bus,
};
static void __exit smsg_exit(void)
{
if (smsg_handle > 0) {
cpcmd("SET SMSG OFF", NULL, 0, NULL);
iucv_sever(smsg_pathid, NULL);
iucv_unregister_program(smsg_handle);
driver_unregister(&smsg_driver);
}
return;
cpcmd("SET SMSG IUCV", NULL, 0, NULL);
iucv_unregister(&smsg_handler, 1);
driver_unregister(&smsg_driver);
}
static int __init
smsg_init(void)
static int __init smsg_init(void)
{
static unsigned char pgmmask[24] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
int rc;
rc = driver_register(&smsg_driver);
if (rc != 0) {
printk(KERN_ERR "SMSGIUCV: failed to register driver.\n");
return rc;
}
smsg_handle = iucv_register_program("SMSGIUCV ", "*MSG ",
pgmmask, &smsg_ops, NULL);
if (!smsg_handle) {
if (rc != 0)
goto out;
rc = iucv_register(&smsg_handler, 1);
if (rc) {
printk(KERN_ERR "SMSGIUCV: failed to register to iucv");
driver_unregister(&smsg_driver);
return -EIO; /* better errno ? */
rc = -EIO; /* better errno ? */
goto out_driver;
}
rc = iucv_connect (&smsg_pathid, 255, NULL, "*MSG ", NULL, 0,
NULL, NULL, smsg_handle, NULL);
smsg_path = iucv_path_alloc(255, 0, GFP_KERNEL);
if (!smsg_path) {
rc = -ENOMEM;
goto out_register;
}
rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ",
NULL, NULL, NULL);
if (rc) {
printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG");
iucv_unregister_program(smsg_handle);
driver_unregister(&smsg_driver);
smsg_handle = NULL;
return -EIO;
rc = -EIO; /* better errno ? */
goto out_free;
}
cpcmd("SET SMSG IUCV", NULL, 0, NULL);
return 0;
out_free:
iucv_path_free(smsg_path);
out_register:
iucv_unregister(&smsg_handler, 1);
out_driver:
driver_unregister(&smsg_driver);
out:
return rc;
}
module_init(smsg_init);

View file

@ -13,22 +13,18 @@
#include <linux/errno.h>
#include <linux/workqueue.h>
#include <linux/time.h>
#include <linux/device.h>
#include <linux/kthread.h>
#include <asm/etr.h>
#include <asm/lowcore.h>
#include <asm/cio.h>
#include "cio/cio.h"
#include "cio/chsc.h"
#include "cio/css.h"
#include "s390mach.h"
static struct semaphore m_sem;
extern int css_process_crw(int, int);
extern int chsc_process_crw(void);
extern int chp_process_crw(int, int);
extern void css_reiterate_subchannels(void);
extern struct workqueue_struct *slow_path_wq;
extern struct work_struct slow_path_work;
static NORET_TYPE void
s390_handle_damage(char *msg)
{
@ -470,6 +466,19 @@ s390_do_machine_check(struct pt_regs *regs)
s390_handle_damage("unable to revalidate registers.");
}
if (mci->cd) {
/* Timing facility damage */
s390_handle_damage("TOD clock damaged");
}
if (mci->ed && mci->ec) {
/* External damage */
if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC))
etr_sync_check();
if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH))
etr_switch_to_local();
}
if (mci->se)
/* Storage error uncorrected */
s390_handle_damage("received storage error uncorrected "
@ -508,7 +517,7 @@ static int
machine_check_init(void)
{
init_MUTEX_LOCKED(&m_sem);
ctl_clear_bit(14, 25); /* disable external damage MCH */
ctl_set_bit(14, 25); /* enable external damage MCH */
ctl_set_bit(14, 27); /* enable system recovery MCH */
#ifdef CONFIG_MACHCHK_WARNING
ctl_set_bit(14, 24); /* enable warning MCH */
@ -529,7 +538,11 @@ arch_initcall(machine_check_init);
static int __init
machine_check_crw_init (void)
{
kthread_run(s390_collect_crw_info, &m_sem, "kmcheck");
struct task_struct *task;
task = kthread_run(s390_collect_crw_info, &m_sem, "kmcheck");
if (IS_ERR(task))
return PTR_ERR(task);
ctl_set_bit(14, 28); /* enable channel report MCH */
return 0;
}

View file

@ -102,4 +102,7 @@ static inline int stcrw(struct crw *pcrw )
return ccode;
}
#define ED_ETR_SYNC 12 /* External damage ETR sync check */
#define ED_ETR_SWITCH 13 /* External damage ETR switch to local */
#endif /* __s390mach */

View file

@ -47,13 +47,12 @@ static int __init zfcp_module_init(void);
static void zfcp_ns_gid_pn_handler(unsigned long);
/* miscellaneous */
static inline int zfcp_sg_list_alloc(struct zfcp_sg_list *, size_t);
static inline void zfcp_sg_list_free(struct zfcp_sg_list *);
static inline int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *,
void __user *, size_t);
static inline int zfcp_sg_list_copy_to_user(void __user *,
struct zfcp_sg_list *, size_t);
static int zfcp_sg_list_alloc(struct zfcp_sg_list *, size_t);
static void zfcp_sg_list_free(struct zfcp_sg_list *);
static int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *,
void __user *, size_t);
static int zfcp_sg_list_copy_to_user(void __user *,
struct zfcp_sg_list *, size_t);
static long zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long);
#define ZFCP_CFDC_IOC_MAGIC 0xDD
@ -605,7 +604,7 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
* elements of the scatter-gather list. The maximum size of a single element
* in the scatter-gather list is PAGE_SIZE.
*/
static inline int
static int
zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
{
struct scatterlist *sg;
@ -652,7 +651,7 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
* Memory for each element in the scatter-gather list is freed.
* Finally sg_list->sg is freed itself and sg_list->count is reset.
*/
static inline void
static void
zfcp_sg_list_free(struct zfcp_sg_list *sg_list)
{
struct scatterlist *sg;
@ -697,7 +696,7 @@ zfcp_sg_size(struct scatterlist *sg, unsigned int sg_count)
* @size: number of bytes to be copied
* Return: 0 on success, -EFAULT if copy_from_user fails.
*/
static inline int
static int
zfcp_sg_list_copy_from_user(struct zfcp_sg_list *sg_list,
void __user *user_buffer,
size_t size)
@ -735,7 +734,7 @@ zfcp_sg_list_copy_from_user(struct zfcp_sg_list *sg_list,
* @size: number of bytes to be copied
* Return: 0 on success, -EFAULT if copy_to_user fails
*/
static inline int
static int
zfcp_sg_list_copy_to_user(void __user *user_buffer,
struct zfcp_sg_list *sg_list,
size_t size)
@ -1799,7 +1798,7 @@ static const struct zfcp_rc_entry zfcp_p_rjt_rc[] = {
* @code: reason code
* @rc_table: table of reason codes and descriptions
*/
static inline const char *
static const char *
zfcp_rc_description(u8 code, const struct zfcp_rc_entry *rc_table)
{
const char *descr = "unknown reason code";
@ -1847,7 +1846,7 @@ zfcp_check_ct_response(struct ct_hdr *rjt)
* @rjt_par: reject parameter acc. to FC-PH/FC-FS
* @rc_table: table of reason codes and descriptions
*/
static inline void
static void
zfcp_print_els_rjt(struct zfcp_ls_rjt_par *rjt_par,
const struct zfcp_rc_entry *rc_table)
{

View file

@ -31,7 +31,7 @@ MODULE_PARM_DESC(dbfsize,
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER
static inline int
static int
zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck)
{
unsigned long long sec;
@ -106,7 +106,7 @@ zfcp_dbf_view_dump(char *out_buf, const char *label,
return len;
}
static inline int
static int
zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,
debug_entry_t * entry, char *out_buf)
{
@ -130,7 +130,7 @@ zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,
return len;
}
inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_adapter *adapter = fsf_req->adapter;
struct fsf_qtcb *qtcb = fsf_req->qtcb;
@ -241,7 +241,7 @@ inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
}
inline void
void
zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
struct fsf_status_read_buffer *status_buffer)
{
@ -295,7 +295,7 @@ zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
}
inline void
void
zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,
unsigned int qdio_error, unsigned int siga_error,
int sbal_index, int sbal_count)
@ -316,7 +316,7 @@ zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,
spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
}
static inline int
static int
zfcp_hba_dbf_view_response(char *out_buf,
struct zfcp_hba_dbf_record_response *rec)
{
@ -403,7 +403,7 @@ zfcp_hba_dbf_view_response(char *out_buf,
return len;
}
static inline int
static int
zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec)
{
int len = 0;
@ -424,7 +424,7 @@ zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec)
return len;
}
static inline int
static int
zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec)
{
int len = 0;
@ -469,7 +469,7 @@ zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view,
return len;
}
struct debug_view zfcp_hba_dbf_view = {
static struct debug_view zfcp_hba_dbf_view = {
"structured",
NULL,
&zfcp_dbf_view_header,
@ -478,7 +478,7 @@ struct debug_view zfcp_hba_dbf_view = {
NULL
};
inline void
void
_zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req,
u32 s_id, u32 d_id, void *buffer, int buflen)
{
@ -519,7 +519,7 @@ _zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req,
spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
}
inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
struct zfcp_port *port = ct->port;
@ -531,7 +531,7 @@ inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
ct->req->length);
}
inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
struct zfcp_port *port = ct->port;
@ -543,7 +543,7 @@ inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
ct->resp->length);
}
static inline void
static void
_zfcp_san_dbf_event_common_els(const char *tag, int level,
struct zfcp_fsf_req *fsf_req, u32 s_id,
u32 d_id, u8 ls_code, void *buffer, int buflen)
@ -585,7 +585,7 @@ _zfcp_san_dbf_event_common_els(const char *tag, int level,
spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
}
inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
@ -597,7 +597,7 @@ inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
els->req->length);
}
inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
@ -608,7 +608,7 @@ inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
els->resp->length);
}
inline void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_adapter *adapter = fsf_req->adapter;
struct fsf_status_read_buffer *status_buffer =
@ -693,7 +693,7 @@ zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view,
return len;
}
struct debug_view zfcp_san_dbf_view = {
static struct debug_view zfcp_san_dbf_view = {
"structured",
NULL,
&zfcp_dbf_view_header,
@ -702,7 +702,7 @@ struct debug_view zfcp_san_dbf_view = {
NULL
};
static inline void
static void
_zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
struct zfcp_adapter *adapter,
struct scsi_cmnd *scsi_cmnd,
@ -786,7 +786,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);
}
inline void
void
zfcp_scsi_dbf_event_result(const char *tag, int level,
struct zfcp_adapter *adapter,
struct scsi_cmnd *scsi_cmnd,
@ -796,7 +796,7 @@ zfcp_scsi_dbf_event_result(const char *tag, int level,
adapter, scsi_cmnd, fsf_req, 0);
}
inline void
void
zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
struct scsi_cmnd *scsi_cmnd,
struct zfcp_fsf_req *new_fsf_req,
@ -806,7 +806,7 @@ zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
adapter, scsi_cmnd, new_fsf_req, old_req_id);
}
inline void
void
zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
struct scsi_cmnd *scsi_cmnd)
{
@ -884,7 +884,7 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
return len;
}
struct debug_view zfcp_scsi_dbf_view = {
static struct debug_view zfcp_scsi_dbf_view = {
"structured",
NULL,
&zfcp_dbf_view_header,

View file

@ -200,7 +200,7 @@ void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout)
* returns: 0 - initiated action successfully
* <0 - failed to initiate action
*/
int
static int
zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
{
int retval;
@ -295,7 +295,7 @@ zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask)
* zfcp_erp_adisc - send ADISC ELS command
* @port: port structure
*/
int
static int
zfcp_erp_adisc(struct zfcp_port *port)
{
struct zfcp_adapter *adapter = port->adapter;
@ -380,7 +380,7 @@ zfcp_erp_adisc(struct zfcp_port *port)
*
* If ADISC failed (LS_RJT or timed out) forced reopen of the port is triggered.
*/
void
static void
zfcp_erp_adisc_handler(unsigned long data)
{
struct zfcp_send_els *send_els;
@ -3135,7 +3135,6 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
break;
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
if (result != ZFCP_ERP_SUCCEEDED) {
struct zfcp_port *port;
list_for_each_entry(port, &adapter->port_list_head, list)
if (port->rport &&
!atomic_test_mask(ZFCP_STATUS_PORT_WKA,

View file

@ -119,8 +119,8 @@ extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t);
extern char *zfcp_get_fcp_rsp_info_ptr(struct fcp_rsp_iu *);
extern void set_host_byte(u32 *, char);
extern void set_driver_byte(u32 *, char);
extern void set_host_byte(int *, char);
extern void set_driver_byte(int *, char);
extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
extern fcp_dl_t zfcp_get_fcp_dl(struct fcp_cmnd_iu *);

View file

@ -4560,7 +4560,7 @@ zfcp_fsf_req_sbal_check(unsigned long *flags,
/*
* set qtcb pointer in fsf_req and initialize QTCB
*/
static inline void
static void
zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req)
{
if (likely(fsf_req->qtcb != NULL)) {

View file

@ -21,22 +21,22 @@
#include "zfcp_ext.h"
static inline void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *, int);
static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *, int);
static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_get
(struct zfcp_qdio_queue *, int, int);
static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_resp
(struct zfcp_fsf_req *, int, int);
static inline volatile struct qdio_buffer_element *zfcp_qdio_sbal_chain
static volatile struct qdio_buffer_element *zfcp_qdio_sbal_chain
(struct zfcp_fsf_req *, unsigned long);
static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_next
static volatile struct qdio_buffer_element *zfcp_qdio_sbale_next
(struct zfcp_fsf_req *, unsigned long);
static inline int zfcp_qdio_sbals_zero(struct zfcp_qdio_queue *, int, int);
static int zfcp_qdio_sbals_zero(struct zfcp_qdio_queue *, int, int);
static inline int zfcp_qdio_sbals_wipe(struct zfcp_fsf_req *);
static inline void zfcp_qdio_sbale_fill
static void zfcp_qdio_sbale_fill
(struct zfcp_fsf_req *, unsigned long, void *, int);
static inline int zfcp_qdio_sbals_from_segment
static int zfcp_qdio_sbals_from_segment
(struct zfcp_fsf_req *, unsigned long, void *, unsigned long);
static inline int zfcp_qdio_sbals_from_buffer
static int zfcp_qdio_sbals_from_buffer
(struct zfcp_fsf_req *, unsigned long, void *, unsigned long, int);
static qdio_handler_t zfcp_qdio_request_handler;
@ -201,7 +201,7 @@ zfcp_qdio_allocate(struct zfcp_adapter *adapter)
* returns: error flag
*
*/
static inline int
static int
zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,
unsigned int qdio_error, unsigned int siga_error,
int first_element, int elements_processed)
@ -462,7 +462,7 @@ zfcp_qdio_sbale_get(struct zfcp_qdio_queue *queue, int sbal, int sbale)
* zfcp_qdio_sbale_req - return pointer to SBALE of request_queue for
* a struct zfcp_fsf_req
*/
inline volatile struct qdio_buffer_element *
volatile struct qdio_buffer_element *
zfcp_qdio_sbale_req(struct zfcp_fsf_req *fsf_req, int sbal, int sbale)
{
return zfcp_qdio_sbale_get(&fsf_req->adapter->request_queue,
@ -484,7 +484,7 @@ zfcp_qdio_sbale_resp(struct zfcp_fsf_req *fsf_req, int sbal, int sbale)
* zfcp_qdio_sbale_curr - return current SBALE on request_queue for
* a struct zfcp_fsf_req
*/
inline volatile struct qdio_buffer_element *
volatile struct qdio_buffer_element *
zfcp_qdio_sbale_curr(struct zfcp_fsf_req *fsf_req)
{
return zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr,
@ -499,7 +499,7 @@ zfcp_qdio_sbale_curr(struct zfcp_fsf_req *fsf_req)
*
* Note: We can assume at least one free SBAL in the request_queue when called.
*/
static inline void
static void
zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals)
{
int count = atomic_read(&fsf_req->adapter->request_queue.free_count);
@ -517,7 +517,7 @@ zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals)
*
* This function changes sbal_curr, sbale_curr, sbal_number of fsf_req.
*/
static inline volatile struct qdio_buffer_element *
static volatile struct qdio_buffer_element *
zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
{
volatile struct qdio_buffer_element *sbale;
@ -554,7 +554,7 @@ zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
/**
* zfcp_qdio_sbale_next - switch to next SBALE, chain SBALs if needed
*/
static inline volatile struct qdio_buffer_element *
static volatile struct qdio_buffer_element *
zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
{
if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL)
@ -569,7 +569,7 @@ zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
* zfcp_qdio_sbals_zero - initialize SBALs between first and last in queue
* with zero from
*/
static inline int
static int
zfcp_qdio_sbals_zero(struct zfcp_qdio_queue *queue, int first, int last)
{
struct qdio_buffer **buf = queue->buffer;
@ -603,7 +603,7 @@ zfcp_qdio_sbals_wipe(struct zfcp_fsf_req *fsf_req)
* zfcp_qdio_sbale_fill - set address and lenght in current SBALE
* on request_queue
*/
static inline void
static void
zfcp_qdio_sbale_fill(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
void *addr, int length)
{
@ -624,7 +624,7 @@ zfcp_qdio_sbale_fill(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
* Alignment and length of the segment determine how many SBALEs are needed
* for the memory segment.
*/
static inline int
static int
zfcp_qdio_sbals_from_segment(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
void *start_addr, unsigned long total_length)
{
@ -659,7 +659,7 @@ zfcp_qdio_sbals_from_segment(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
* @sg_count: number of elements in scatter-gather list
* @max_sbals: upper bound for number of SBALs to be used
*/
inline int
int
zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
struct scatterlist *sg, int sg_count, int max_sbals)
{
@ -707,7 +707,7 @@ out:
* @length: length of buffer
* @max_sbals: upper bound for number of SBALs to be used
*/
static inline int
static int
zfcp_qdio_sbals_from_buffer(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
void *buffer, unsigned long length, int max_sbals)
{
@ -728,7 +728,7 @@ zfcp_qdio_sbals_from_buffer(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
* @scsi_cmnd: either scatter-gather list or buffer contained herein is used
* to fill SBALs
*/
inline int
int
zfcp_qdio_sbals_from_scsicmnd(struct zfcp_fsf_req *fsf_req,
unsigned long sbtype, struct scsi_cmnd *scsi_cmnd)
{

View file

@ -90,7 +90,7 @@ zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
return fcp_sns_info_ptr;
}
fcp_dl_t *
static fcp_dl_t *
zfcp_get_fcp_dl_ptr(struct fcp_cmnd_iu * fcp_cmd)
{
int additional_length = fcp_cmd->add_fcp_cdb_length << 2;
@ -124,19 +124,19 @@ zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, fcp_dl_t fcp_dl)
* regarding the specified byte
*/
static inline void
set_byte(u32 * result, char status, char pos)
set_byte(int *result, char status, char pos)
{
*result |= status << (pos * 8);
}
void
set_host_byte(u32 * result, char status)
set_host_byte(int *result, char status)
{
set_byte(result, status, 2);
}
void
set_driver_byte(u32 * result, char status)
set_driver_byte(int *result, char status)
{
set_byte(result, status, 3);
}
@ -280,7 +280,7 @@ out:
return retval;
}
void
static void
zfcp_scsi_command_sync_handler(struct scsi_cmnd *scpnt)
{
struct completion *wait = (struct completion *) scpnt->SCp.ptr;
@ -324,7 +324,7 @@ zfcp_scsi_command_sync(struct zfcp_unit *unit, struct scsi_cmnd *scpnt,
* returns: 0 - success, SCSI command enqueued
* !0 - failure
*/
int
static int
zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
void (*done) (struct scsi_cmnd *))
{
@ -380,7 +380,7 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id,
* will handle late commands. (Usually, the normal completion of late
* commands is ignored with respect to the running abort operation.)
*/
int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
{
struct Scsi_Host *scsi_host;
struct zfcp_adapter *adapter;
@ -445,7 +445,7 @@ int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
return retval;
}
int
static int
zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
{
int retval;
@ -541,7 +541,7 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags,
/**
* zfcp_scsi_eh_host_reset_handler - handler for host and bus reset
*/
int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
{
struct zfcp_unit *unit;
struct zfcp_adapter *adapter;

View file

@ -9,8 +9,14 @@
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/ebcdic.h>
/* Sigh, math-emu. Don't ask. */
#include <asm/sfp-util.h>
#include <math-emu/soft-fp.h>
#include <math-emu/single.h>
struct sysinfo_1_1_1 {
char reserved_0[32];
char manufacturer[16];
@ -198,7 +204,7 @@ static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
* if the higher order 8 bits are not zero. Printing
* a floating point number in the kernel is a no-no,
* always print the number as 32 bit unsigned integer.
* The user-space needs to know about the stange
* The user-space needs to know about the strange
* encoding of the alternate cpu capability.
*/
len += sprintf(page + len, "Capability: %u %u\n",
@ -351,3 +357,58 @@ static __init int create_proc_sysinfo(void)
__initcall(create_proc_sysinfo);
/*
* CPU capability might have changed. Therefore recalculate loops_per_jiffy.
*/
void s390_adjust_jiffies(void)
{
struct sysinfo_1_2_2 *info;
const unsigned int fmil = 0x4b189680; /* 1e7 as 32-bit float. */
FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
FP_DECL_EX;
unsigned int capability;
info = (void *) get_zeroed_page(GFP_KERNEL);
if (!info)
return;
if (stsi(info, 1, 2, 2) != -ENOSYS) {
/*
* Major sigh. The cpu capability encoding is "special".
* If the first 9 bits of info->capability are 0 then it
* is a 32 bit unsigned integer in the range 0 .. 2^23.
* If the first 9 bits are != 0 then it is a 32 bit float.
* In addition a lower value indicates a proportionally
* higher cpu capacity. Bogomips are the other way round.
* To get to a halfway suitable number we divide 1e7
* by the cpu capability number. Yes, that means a floating
* point division .. math-emu here we come :-)
*/
FP_UNPACK_SP(SA, &fmil);
if ((info->capability >> 23) == 0)
FP_FROM_INT_S(SB, info->capability, 32, int);
else
FP_UNPACK_SP(SB, &info->capability);
FP_DIV_S(SR, SA, SB);
FP_TO_INT_S(capability, SR, 32, 0);
} else
/*
* Really old machine without stsi block for basic
* cpu information. Report 42.0 bogomips.
*/
capability = 42;
loops_per_jiffy = capability * (500000/HZ);
free_page((unsigned long) info);
}
/*
* calibrate the delay loop
*/
void __init calibrate_delay(void)
{
s390_adjust_jiffies();
/* Print the good old Bogomips line .. */
printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
"%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
(loops_per_jiffy/(5000/HZ)) % 100);
}