Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 135591
b: refs/heads/master
c: f3eb538
h: refs/heads/master
i:
  135589: 03b0ccb
  135587: fa5b7ef
  135583: 7731bfe
v: v3
  • Loading branch information
Stefan Weinhuber authored and Martin Schwidefsky committed Mar 26, 2009
1 parent fcdbb25 commit d369b4f
Show file tree
Hide file tree
Showing 10 changed files with 1,124 additions and 176 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b44b0ab3bac16356f03e94b1b49ba9305710c445
refs/heads/master: f3eb5384cf0325c02e306b1d81e70f81a03d7432
17 changes: 5 additions & 12 deletions trunk/arch/s390/include/asm/idals.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,18 @@ idal_is_needed(void *vaddr, unsigned int length)
/*
* Return the number of idal words needed for an address/length pair.
*/
static inline unsigned int
idal_nr_words(void *vaddr, unsigned int length)
static inline unsigned int idal_nr_words(void *vaddr, unsigned int length)
{
#ifdef __s390x__
if (idal_is_needed(vaddr, length))
return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length +
(IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
#endif
return 0;
return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length +
(IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
}

/*
* Create the list of idal words for an address/length pair.
*/
static inline unsigned long *
idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length)
static inline unsigned long *idal_create_words(unsigned long *idaws,
void *vaddr, unsigned int length)
{
#ifdef __s390x__
unsigned long paddr;
unsigned int cidaw;

Expand All @@ -74,7 +68,6 @@ idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length)
paddr += IDA_BLOCK_SIZE;
*idaws++ = paddr;
}
#endif
return idaws;
}

Expand Down
70 changes: 58 additions & 12 deletions trunk/drivers/s390/block/dasd.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <asm/ebcdic.h>
#include <asm/idals.h>
#include <asm/todclk.h>
#include <asm/itcw.h>

/* This is ugly... */
#define PRINTK_HEADER "dasd:"
Expand Down Expand Up @@ -852,8 +853,13 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
cqr->startclk = get_clock();
cqr->starttime = jiffies;
cqr->retries--;
rc = ccw_device_start(device->cdev, cqr->cpaddr, (long) cqr,
cqr->lpm, 0);
if (cqr->cpmode == 1) {
rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
(long) cqr, cqr->lpm);
} else {
rc = ccw_device_start(device->cdev, cqr->cpaddr,
(long) cqr, cqr->lpm, 0);
}
switch (rc) {
case 0:
cqr->status = DASD_CQR_IN_IO;
Expand Down Expand Up @@ -881,9 +887,12 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
" retry on all pathes");
break;
case -ENODEV:
DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: -ENODEV device gone, retry");
break;
case -EIO:
DBF_DEV_EVENT(DBF_ERR, device, "%s",
"start_IO: device gone, retry");
"start_IO: -EIO device gone, retry");
break;
default:
DEV_MESSAGE(KERN_ERR, device,
Expand Down Expand Up @@ -1015,9 +1024,9 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,

/* check for unsolicited interrupts */
cqr = (struct dasd_ccw_req *) intparm;
if (!cqr || ((irb->scsw.cmd.cc == 1) &&
(irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
(irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) {
if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
(scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) {
if (cqr && cqr->status == DASD_CQR_IN_IO)
cqr->status = DASD_CQR_QUEUED;
device = dasd_device_from_cdev_locked(cdev);
Expand All @@ -1040,15 +1049,15 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,

/* Check for clear pending */
if (cqr->status == DASD_CQR_CLEAR_PENDING &&
irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) {
scsw_fctl(&irb->scsw) & SCSW_FCTL_CLEAR_FUNC) {
cqr->status = DASD_CQR_CLEARED;
dasd_device_clear_timer(device);
wake_up(&dasd_flush_wq);
dasd_schedule_device_bh(device);
return;
}

/* check status - the request might have been killed by dyn detach */
/* check status - the request might have been killed by dyn detach */
if (cqr->status != DASD_CQR_IN_IO) {
MESSAGE(KERN_DEBUG,
"invalid status: bus_id %s, status %02x",
Expand All @@ -1059,8 +1068,8 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr);
next = NULL;
expires = 0;
if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) {
if (scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
scsw_cstat(&irb->scsw) == 0) {
/* request was completed successfully */
cqr->status = DASD_CQR_SUCCESS;
cqr->stopclk = now;
Expand Down Expand Up @@ -1991,8 +2000,11 @@ static void dasd_setup_queue(struct dasd_block *block)
blk_queue_max_sectors(block->request_queue, max);
blk_queue_max_phys_segments(block->request_queue, -1L);
blk_queue_max_hw_segments(block->request_queue, -1L);
blk_queue_max_segment_size(block->request_queue, -1L);
blk_queue_segment_boundary(block->request_queue, -1L);
/* with page sized segments we can translate each segement into
* one idaw/tidaw
*/
blk_queue_max_segment_size(block->request_queue, PAGE_SIZE);
blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1);
blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL);
}

Expand Down Expand Up @@ -2432,6 +2444,40 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic,
}
EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars);

/*
* In command mode and transport mode we need to look for sense
* data in different places. The sense data itself is allways
* an array of 32 bytes, so we can unify the sense data access
* for both modes.
*/
char *dasd_get_sense(struct irb *irb)
{
struct tsb *tsb = NULL;
char *sense = NULL;

if (scsw_is_tm(&irb->scsw) && (irb->scsw.tm.fcxs == 0x01)) {
if (irb->scsw.tm.tcw)
tsb = tcw_get_tsb((struct tcw *)(unsigned long)
irb->scsw.tm.tcw);
if (tsb && tsb->length == 64 && tsb->flags)
switch (tsb->flags & 0x07) {
case 1: /* tsa_iostat */
sense = tsb->tsa.iostat.sense;
break;
case 2: /* tsa_ddpc */
sense = tsb->tsa.ddpc.sense;
break;
default:
/* currently we don't use interrogate data */
break;
}
} else if (irb->esw.esw0.erw.cons) {
sense = irb->ecw;
}
return sense;
}
EXPORT_SYMBOL_GPL(dasd_get_sense);

static int __init dasd_init(void)
{
int rc;
Expand Down
Loading

0 comments on commit d369b4f

Please sign in to comment.