diff options
Diffstat (limited to 'drivers/s390')
27 files changed, 375 insertions, 838 deletions
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 231a1d85127b..36506366158d 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
@@ -352,7 +352,17 @@ out: | |||
352 | 352 | ||
353 | static int sclp_assign_storage(u16 rn) | 353 | static int sclp_assign_storage(u16 rn) |
354 | { | 354 | { |
355 | return do_assign_storage(0x000d0001, rn); | 355 | unsigned long long start, address; |
356 | int rc; | ||
357 | |||
358 | rc = do_assign_storage(0x000d0001, rn); | ||
359 | if (rc) | ||
360 | goto out; | ||
361 | start = address = rn2addr(rn); | ||
362 | for (; address < start + rzm; address += PAGE_SIZE) | ||
363 | page_set_storage_key(address, PAGE_DEFAULT_KEY, 0); | ||
364 | out: | ||
365 | return rc; | ||
356 | } | 366 | } |
357 | 367 | ||
358 | static int sclp_unassign_storage(u16 rn) | 368 | static int sclp_unassign_storage(u16 rn) |
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 267b54e8ff5a..bc6c7cfd36b6 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h | |||
@@ -154,12 +154,6 @@ struct tape_discipline { | |||
154 | struct tape_request *(*read_block)(struct tape_device *, size_t); | 154 | struct tape_request *(*read_block)(struct tape_device *, size_t); |
155 | struct tape_request *(*write_block)(struct tape_device *, size_t); | 155 | struct tape_request *(*write_block)(struct tape_device *, size_t); |
156 | void (*process_eov)(struct tape_device*); | 156 | void (*process_eov)(struct tape_device*); |
157 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
158 | /* Block device stuff. */ | ||
159 | struct tape_request *(*bread)(struct tape_device *, struct request *); | ||
160 | void (*check_locate)(struct tape_device *, struct tape_request *); | ||
161 | void (*free_bread)(struct tape_request *); | ||
162 | #endif | ||
163 | /* ioctl function for additional ioctls. */ | 157 | /* ioctl function for additional ioctls. */ |
164 | int (*ioctl_fn)(struct tape_device *, unsigned int, unsigned long); | 158 | int (*ioctl_fn)(struct tape_device *, unsigned int, unsigned long); |
165 | /* Array of tape commands with TAPE_NR_MTOPS entries */ | 159 | /* Array of tape commands with TAPE_NR_MTOPS entries */ |
@@ -182,26 +176,6 @@ struct tape_char_data { | |||
182 | int block_size; /* of size block_size. */ | 176 | int block_size; /* of size block_size. */ |
183 | }; | 177 | }; |
184 | 178 | ||
185 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
186 | /* Block Frontend Data */ | ||
187 | struct tape_blk_data | ||
188 | { | ||
189 | struct tape_device * device; | ||
190 | /* Block device request queue. */ | ||
191 | struct request_queue * request_queue; | ||
192 | spinlock_t request_queue_lock; | ||
193 | |||
194 | /* Task to move entries from block request to CCS request queue. */ | ||
195 | struct work_struct requeue_task; | ||
196 | atomic_t requeue_scheduled; | ||
197 | |||
198 | /* Current position on the tape. */ | ||
199 | long block_position; | ||
200 | int medium_changed; | ||
201 | struct gendisk * disk; | ||
202 | }; | ||
203 | #endif | ||
204 | |||
205 | /* Tape Info */ | 179 | /* Tape Info */ |
206 | struct tape_device { | 180 | struct tape_device { |
207 | /* entry in tape_device_list */ | 181 | /* entry in tape_device_list */ |
@@ -248,10 +222,6 @@ struct tape_device { | |||
248 | 222 | ||
249 | /* Character device frontend data */ | 223 | /* Character device frontend data */ |
250 | struct tape_char_data char_data; | 224 | struct tape_char_data char_data; |
251 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
252 | /* Block dev frontend data */ | ||
253 | struct tape_blk_data blk_data; | ||
254 | #endif | ||
255 | 225 | ||
256 | /* Function to start or stop the next request later. */ | 226 | /* Function to start or stop the next request later. */ |
257 | struct delayed_work tape_dnr; | 227 | struct delayed_work tape_dnr; |
@@ -313,19 +283,6 @@ extern void tapechar_exit(void); | |||
313 | extern int tapechar_setup_device(struct tape_device *); | 283 | extern int tapechar_setup_device(struct tape_device *); |
314 | extern void tapechar_cleanup_device(struct tape_device *); | 284 | extern void tapechar_cleanup_device(struct tape_device *); |
315 | 285 | ||
316 | /* Externals from tape_block.c */ | ||
317 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
318 | extern int tapeblock_init (void); | ||
319 | extern void tapeblock_exit(void); | ||
320 | extern int tapeblock_setup_device(struct tape_device *); | ||
321 | extern void tapeblock_cleanup_device(struct tape_device *); | ||
322 | #else | ||
323 | static inline int tapeblock_init (void) {return 0;} | ||
324 | static inline void tapeblock_exit (void) {;} | ||
325 | static inline int tapeblock_setup_device(struct tape_device *t) {return 0;} | ||
326 | static inline void tapeblock_cleanup_device (struct tape_device *t) {;} | ||
327 | #endif | ||
328 | |||
329 | /* tape initialisation functions */ | 286 | /* tape initialisation functions */ |
330 | #ifdef CONFIG_PROC_FS | 287 | #ifdef CONFIG_PROC_FS |
331 | extern void tape_proc_init (void); | 288 | extern void tape_proc_init (void); |
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 934ef33eb9a4..b28de80b7ca4 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -323,20 +323,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request, | |||
323 | inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0; | 323 | inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0; |
324 | sense = irb->ecw; | 324 | sense = irb->ecw; |
325 | 325 | ||
326 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
327 | if (request->op == TO_BLOCK) { | ||
328 | /* | ||
329 | * Recovery for block device requests. Set the block_position | ||
330 | * to something invalid and retry. | ||
331 | */ | ||
332 | device->blk_data.block_position = -1; | ||
333 | if (request->retries-- <= 0) | ||
334 | return tape_34xx_erp_failed(request, -EIO); | ||
335 | else | ||
336 | return tape_34xx_erp_retry(request); | ||
337 | } | ||
338 | #endif | ||
339 | |||
340 | if ( | 326 | if ( |
341 | sense[0] & SENSE_COMMAND_REJECT && | 327 | sense[0] & SENSE_COMMAND_REJECT && |
342 | sense[1] & SENSE_WRITE_PROTECT | 328 | sense[1] & SENSE_WRITE_PROTECT |
@@ -1129,123 +1115,6 @@ tape_34xx_mtseek(struct tape_device *device, int mt_count) | |||
1129 | return tape_do_io_free(device, request); | 1115 | return tape_do_io_free(device, request); |
1130 | } | 1116 | } |
1131 | 1117 | ||
1132 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
1133 | /* | ||
1134 | * Tape block read for 34xx. | ||
1135 | */ | ||
1136 | static struct tape_request * | ||
1137 | tape_34xx_bread(struct tape_device *device, struct request *req) | ||
1138 | { | ||
1139 | struct tape_request *request; | ||
1140 | struct ccw1 *ccw; | ||
1141 | int count = 0; | ||
1142 | unsigned off; | ||
1143 | char *dst; | ||
1144 | struct bio_vec *bv; | ||
1145 | struct req_iterator iter; | ||
1146 | struct tape_34xx_block_id * start_block; | ||
1147 | |||
1148 | DBF_EVENT(6, "xBREDid:"); | ||
1149 | |||
1150 | /* Count the number of blocks for the request. */ | ||
1151 | rq_for_each_segment(bv, req, iter) | ||
1152 | count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); | ||
1153 | |||
1154 | /* Allocate the ccw request. */ | ||
1155 | request = tape_alloc_request(3+count+1, 8); | ||
1156 | if (IS_ERR(request)) | ||
1157 | return request; | ||
1158 | |||
1159 | /* Setup ccws. */ | ||
1160 | request->op = TO_BLOCK; | ||
1161 | start_block = (struct tape_34xx_block_id *) request->cpdata; | ||
1162 | start_block->block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B; | ||
1163 | DBF_EVENT(6, "start_block = %i\n", start_block->block); | ||
1164 | |||
1165 | ccw = request->cpaddr; | ||
1166 | ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte); | ||
1167 | |||
1168 | /* | ||
1169 | * We always setup a nop after the mode set ccw. This slot is | ||
1170 | * used in tape_std_check_locate to insert a locate ccw if the | ||
1171 | * current tape position doesn't match the start block to be read. | ||
1172 | * The second nop will be filled with a read block id which is in | ||
1173 | * turn used by tape_34xx_free_bread to populate the segment bid | ||
1174 | * table. | ||
1175 | */ | ||
1176 | ccw = tape_ccw_cc(ccw, NOP, 0, NULL); | ||
1177 | ccw = tape_ccw_cc(ccw, NOP, 0, NULL); | ||
1178 | |||
1179 | rq_for_each_segment(bv, req, iter) { | ||
1180 | dst = kmap(bv->bv_page) + bv->bv_offset; | ||
1181 | for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) { | ||
1182 | ccw->flags = CCW_FLAG_CC; | ||
1183 | ccw->cmd_code = READ_FORWARD; | ||
1184 | ccw->count = TAPEBLOCK_HSEC_SIZE; | ||
1185 | set_normalized_cda(ccw, (void*) __pa(dst)); | ||
1186 | ccw++; | ||
1187 | dst += TAPEBLOCK_HSEC_SIZE; | ||
1188 | } | ||
1189 | } | ||
1190 | |||
1191 | ccw = tape_ccw_end(ccw, NOP, 0, NULL); | ||
1192 | DBF_EVENT(6, "xBREDccwg\n"); | ||
1193 | return request; | ||
1194 | } | ||
1195 | |||
1196 | static void | ||
1197 | tape_34xx_free_bread (struct tape_request *request) | ||
1198 | { | ||
1199 | struct ccw1* ccw; | ||
1200 | |||
1201 | ccw = request->cpaddr; | ||
1202 | if ((ccw + 2)->cmd_code == READ_BLOCK_ID) { | ||
1203 | struct { | ||
1204 | struct tape_34xx_block_id cbid; | ||
1205 | struct tape_34xx_block_id dbid; | ||
1206 | } __attribute__ ((packed)) *rbi_data; | ||
1207 | |||
1208 | rbi_data = request->cpdata; | ||
1209 | |||
1210 | if (request->device) | ||
1211 | tape_34xx_add_sbid(request->device, rbi_data->cbid); | ||
1212 | } | ||
1213 | |||
1214 | /* Last ccw is a nop and doesn't need clear_normalized_cda */ | ||
1215 | for (; ccw->flags & CCW_FLAG_CC; ccw++) | ||
1216 | if (ccw->cmd_code == READ_FORWARD) | ||
1217 | clear_normalized_cda(ccw); | ||
1218 | tape_free_request(request); | ||
1219 | } | ||
1220 | |||
1221 | /* | ||
1222 | * check_locate is called just before the tape request is passed to | ||
1223 | * the common io layer for execution. It has to check the current | ||
1224 | * tape position and insert a locate ccw if it doesn't match the | ||
1225 | * start block for the request. | ||
1226 | */ | ||
1227 | static void | ||
1228 | tape_34xx_check_locate(struct tape_device *device, struct tape_request *request) | ||
1229 | { | ||
1230 | struct tape_34xx_block_id * start_block; | ||
1231 | |||
1232 | start_block = (struct tape_34xx_block_id *) request->cpdata; | ||
1233 | if (start_block->block == device->blk_data.block_position) | ||
1234 | return; | ||
1235 | |||
1236 | DBF_LH(4, "Block seek(%06d+%06d)\n", start_block->block, device->bof); | ||
1237 | start_block->wrap = 0; | ||
1238 | start_block->segment = 1; | ||
1239 | start_block->format = (*device->modeset_byte & 0x08) ? | ||
1240 | TAPE34XX_FMT_3480_XF : | ||
1241 | TAPE34XX_FMT_3480; | ||
1242 | start_block->block = start_block->block + device->bof; | ||
1243 | tape_34xx_merge_sbid(device, start_block); | ||
1244 | tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata); | ||
1245 | tape_ccw_cc(request->cpaddr + 2, READ_BLOCK_ID, 8, request->cpdata); | ||
1246 | } | ||
1247 | #endif | ||
1248 | |||
1249 | /* | 1118 | /* |
1250 | * List of 3480/3490 magnetic tape commands. | 1119 | * List of 3480/3490 magnetic tape commands. |
1251 | */ | 1120 | */ |
@@ -1295,11 +1164,6 @@ static struct tape_discipline tape_discipline_34xx = { | |||
1295 | .irq = tape_34xx_irq, | 1164 | .irq = tape_34xx_irq, |
1296 | .read_block = tape_std_read_block, | 1165 | .read_block = tape_std_read_block, |
1297 | .write_block = tape_std_write_block, | 1166 | .write_block = tape_std_write_block, |
1298 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
1299 | .bread = tape_34xx_bread, | ||
1300 | .free_bread = tape_34xx_free_bread, | ||
1301 | .check_locate = tape_34xx_check_locate, | ||
1302 | #endif | ||
1303 | .ioctl_fn = tape_34xx_ioctl, | 1167 | .ioctl_fn = tape_34xx_ioctl, |
1304 | .mtop_array = tape_34xx_mtop | 1168 | .mtop_array = tape_34xx_mtop |
1305 | }; | 1169 | }; |
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 49c6aab7ad78..a5c6614b0db2 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -670,92 +670,6 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op) | |||
670 | return 0; | 670 | return 0; |
671 | } | 671 | } |
672 | 672 | ||
673 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
674 | /* | ||
675 | * Tape Block READ | ||
676 | */ | ||
677 | static struct tape_request * | ||
678 | tape_3590_bread(struct tape_device *device, struct request *req) | ||
679 | { | ||
680 | struct tape_request *request; | ||
681 | struct ccw1 *ccw; | ||
682 | int count = 0, start_block; | ||
683 | unsigned off; | ||
684 | char *dst; | ||
685 | struct bio_vec *bv; | ||
686 | struct req_iterator iter; | ||
687 | |||
688 | DBF_EVENT(6, "xBREDid:"); | ||
689 | start_block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B; | ||
690 | DBF_EVENT(6, "start_block = %i\n", start_block); | ||
691 | |||
692 | rq_for_each_segment(bv, req, iter) | ||
693 | count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); | ||
694 | |||
695 | request = tape_alloc_request(2 + count + 1, 4); | ||
696 | if (IS_ERR(request)) | ||
697 | return request; | ||
698 | request->op = TO_BLOCK; | ||
699 | *(__u32 *) request->cpdata = start_block; | ||
700 | ccw = request->cpaddr; | ||
701 | ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte); | ||
702 | |||
703 | /* | ||
704 | * We always setup a nop after the mode set ccw. This slot is | ||
705 | * used in tape_std_check_locate to insert a locate ccw if the | ||
706 | * current tape position doesn't match the start block to be read. | ||
707 | */ | ||
708 | ccw = tape_ccw_cc(ccw, NOP, 0, NULL); | ||
709 | |||
710 | rq_for_each_segment(bv, req, iter) { | ||
711 | dst = page_address(bv->bv_page) + bv->bv_offset; | ||
712 | for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) { | ||
713 | ccw->flags = CCW_FLAG_CC; | ||
714 | ccw->cmd_code = READ_FORWARD; | ||
715 | ccw->count = TAPEBLOCK_HSEC_SIZE; | ||
716 | set_normalized_cda(ccw, (void *) __pa(dst)); | ||
717 | ccw++; | ||
718 | dst += TAPEBLOCK_HSEC_SIZE; | ||
719 | } | ||
720 | BUG_ON(off > bv->bv_len); | ||
721 | } | ||
722 | ccw = tape_ccw_end(ccw, NOP, 0, NULL); | ||
723 | DBF_EVENT(6, "xBREDccwg\n"); | ||
724 | return request; | ||
725 | } | ||
726 | |||
727 | static void | ||
728 | tape_3590_free_bread(struct tape_request *request) | ||
729 | { | ||
730 | struct ccw1 *ccw; | ||
731 | |||
732 | /* Last ccw is a nop and doesn't need clear_normalized_cda */ | ||
733 | for (ccw = request->cpaddr; ccw->flags & CCW_FLAG_CC; ccw++) | ||
734 | if (ccw->cmd_code == READ_FORWARD) | ||
735 | clear_normalized_cda(ccw); | ||
736 | tape_free_request(request); | ||
737 | } | ||
738 | |||
739 | /* | ||
740 | * check_locate is called just before the tape request is passed to | ||
741 | * the common io layer for execution. It has to check the current | ||
742 | * tape position and insert a locate ccw if it doesn't match the | ||
743 | * start block for the request. | ||
744 | */ | ||
745 | static void | ||
746 | tape_3590_check_locate(struct tape_device *device, struct tape_request *request) | ||
747 | { | ||
748 | __u32 *start_block; | ||
749 | |||
750 | start_block = (__u32 *) request->cpdata; | ||
751 | if (*start_block != device->blk_data.block_position) { | ||
752 | /* Add the start offset of the file to get the real block. */ | ||
753 | *start_block += device->bof; | ||
754 | tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata); | ||
755 | } | ||
756 | } | ||
757 | #endif | ||
758 | |||
759 | static void tape_3590_med_state_set(struct tape_device *device, | 673 | static void tape_3590_med_state_set(struct tape_device *device, |
760 | struct tape_3590_med_sense *sense) | 674 | struct tape_3590_med_sense *sense) |
761 | { | 675 | { |
@@ -1423,20 +1337,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request, | |||
1423 | { | 1337 | { |
1424 | struct tape_3590_sense *sense; | 1338 | struct tape_3590_sense *sense; |
1425 | 1339 | ||
1426 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
1427 | if (request->op == TO_BLOCK) { | ||
1428 | /* | ||
1429 | * Recovery for block device requests. Set the block_position | ||
1430 | * to something invalid and retry. | ||
1431 | */ | ||
1432 | device->blk_data.block_position = -1; | ||
1433 | if (request->retries-- <= 0) | ||
1434 | return tape_3590_erp_failed(device, request, irb, -EIO); | ||
1435 | else | ||
1436 | return tape_3590_erp_retry(device, request, irb); | ||
1437 | } | ||
1438 | #endif | ||
1439 | |||
1440 | sense = (struct tape_3590_sense *) irb->ecw; | 1340 | sense = (struct tape_3590_sense *) irb->ecw; |
1441 | 1341 | ||
1442 | DBF_EVENT(6, "Unit Check: RQC = %x\n", sense->rc_rqc); | 1342 | DBF_EVENT(6, "Unit Check: RQC = %x\n", sense->rc_rqc); |
@@ -1729,11 +1629,6 @@ static struct tape_discipline tape_discipline_3590 = { | |||
1729 | .irq = tape_3590_irq, | 1629 | .irq = tape_3590_irq, |
1730 | .read_block = tape_std_read_block, | 1630 | .read_block = tape_std_read_block, |
1731 | .write_block = tape_std_write_block, | 1631 | .write_block = tape_std_write_block, |
1732 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
1733 | .bread = tape_3590_bread, | ||
1734 | .free_bread = tape_3590_free_bread, | ||
1735 | .check_locate = tape_3590_check_locate, | ||
1736 | #endif | ||
1737 | .ioctl_fn = tape_3590_ioctl, | 1632 | .ioctl_fn = tape_3590_ioctl, |
1738 | .mtop_array = tape_3590_mtop | 1633 | .mtop_array = tape_3590_mtop |
1739 | }; | 1634 | }; |
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 87cd0ab242de..46886a7578c6 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c | |||
@@ -161,11 +161,6 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) | |||
161 | if (rc) | 161 | if (rc) |
162 | return rc; | 162 | return rc; |
163 | 163 | ||
164 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
165 | /* Changes position. */ | ||
166 | device->blk_data.medium_changed = 1; | ||
167 | #endif | ||
168 | |||
169 | DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size); | 164 | DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size); |
170 | /* Let the discipline build the ccw chain. */ | 165 | /* Let the discipline build the ccw chain. */ |
171 | request = device->discipline->read_block(device, block_size); | 166 | request = device->discipline->read_block(device, block_size); |
@@ -218,11 +213,6 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t | |||
218 | if (rc) | 213 | if (rc) |
219 | return rc; | 214 | return rc; |
220 | 215 | ||
221 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
222 | /* Changes position. */ | ||
223 | device->blk_data.medium_changed = 1; | ||
224 | #endif | ||
225 | |||
226 | DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size); | 216 | DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size); |
227 | DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks); | 217 | DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks); |
228 | /* Let the discipline build the ccw chain. */ | 218 | /* Let the discipline build the ccw chain. */ |
@@ -379,9 +369,6 @@ __tapechar_ioctl(struct tape_device *device, | |||
379 | case MTBSFM: | 369 | case MTBSFM: |
380 | case MTFSFM: | 370 | case MTFSFM: |
381 | case MTSEEK: | 371 | case MTSEEK: |
382 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
383 | device->blk_data.medium_changed = 1; | ||
384 | #endif | ||
385 | if (device->required_tapemarks) | 372 | if (device->required_tapemarks) |
386 | tape_std_terminate_write(device); | 373 | tape_std_terminate_write(device); |
387 | default: | 374 | default: |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index b3a3e8e8656e..585618663ba4 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -401,9 +401,6 @@ tape_generic_online(struct tape_device *device, | |||
401 | rc = tapechar_setup_device(device); | 401 | rc = tapechar_setup_device(device); |
402 | if (rc) | 402 | if (rc) |
403 | goto out_minor; | 403 | goto out_minor; |
404 | rc = tapeblock_setup_device(device); | ||
405 | if (rc) | ||
406 | goto out_char; | ||
407 | 404 | ||
408 | tape_state_set(device, TS_UNUSED); | 405 | tape_state_set(device, TS_UNUSED); |
409 | 406 | ||
@@ -411,8 +408,6 @@ tape_generic_online(struct tape_device *device, | |||
411 | 408 | ||
412 | return 0; | 409 | return 0; |
413 | 410 | ||
414 | out_char: | ||
415 | tapechar_cleanup_device(device); | ||
416 | out_minor: | 411 | out_minor: |
417 | tape_remove_minor(device); | 412 | tape_remove_minor(device); |
418 | out_discipline: | 413 | out_discipline: |
@@ -426,7 +421,6 @@ out: | |||
426 | static void | 421 | static void |
427 | tape_cleanup_device(struct tape_device *device) | 422 | tape_cleanup_device(struct tape_device *device) |
428 | { | 423 | { |
429 | tapeblock_cleanup_device(device); | ||
430 | tapechar_cleanup_device(device); | 424 | tapechar_cleanup_device(device); |
431 | device->discipline->cleanup_device(device); | 425 | device->discipline->cleanup_device(device); |
432 | module_put(device->discipline->owner); | 426 | module_put(device->discipline->owner); |
@@ -785,10 +779,6 @@ __tape_start_io(struct tape_device *device, struct tape_request *request) | |||
785 | { | 779 | { |
786 | int rc; | 780 | int rc; |
787 | 781 | ||
788 | #ifdef CONFIG_S390_TAPE_BLOCK | ||
789 | if (request->op == TO_BLOCK) | ||
790 | device->discipline->check_locate(device, request); | ||
791 | #endif | ||
792 | rc = ccw_device_start( | 782 | rc = ccw_device_start( |
793 | device->cdev, | 783 | device->cdev, |
794 | request->cpaddr, | 784 | request->cpaddr, |
@@ -1253,7 +1243,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
1253 | } | 1243 | } |
1254 | 1244 | ||
1255 | /* | 1245 | /* |
1256 | * Tape device open function used by tape_char & tape_block frontends. | 1246 | * Tape device open function used by tape_char frontend. |
1257 | */ | 1247 | */ |
1258 | int | 1248 | int |
1259 | tape_open(struct tape_device *device) | 1249 | tape_open(struct tape_device *device) |
@@ -1283,7 +1273,7 @@ tape_open(struct tape_device *device) | |||
1283 | } | 1273 | } |
1284 | 1274 | ||
1285 | /* | 1275 | /* |
1286 | * Tape device release function used by tape_char & tape_block frontends. | 1276 | * Tape device release function used by tape_char frontend. |
1287 | */ | 1277 | */ |
1288 | int | 1278 | int |
1289 | tape_release(struct tape_device *device) | 1279 | tape_release(struct tape_device *device) |
@@ -1344,7 +1334,6 @@ tape_init (void) | |||
1344 | DBF_EVENT(3, "tape init\n"); | 1334 | DBF_EVENT(3, "tape init\n"); |
1345 | tape_proc_init(); | 1335 | tape_proc_init(); |
1346 | tapechar_init (); | 1336 | tapechar_init (); |
1347 | tapeblock_init (); | ||
1348 | return 0; | 1337 | return 0; |
1349 | } | 1338 | } |
1350 | 1339 | ||
@@ -1358,7 +1347,6 @@ tape_exit(void) | |||
1358 | 1347 | ||
1359 | /* Get rid of the frontends */ | 1348 | /* Get rid of the frontends */ |
1360 | tapechar_exit(); | 1349 | tapechar_exit(); |
1361 | tapeblock_exit(); | ||
1362 | tape_proc_cleanup(); | 1350 | tape_proc_cleanup(); |
1363 | debug_unregister (TAPE_DBF_AREA); | 1351 | debug_unregister (TAPE_DBF_AREA); |
1364 | } | 1352 | } |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 5f1dc6fb5708..731470e68493 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * bus driver for ccwgroup | 2 | * bus driver for ccwgroup |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2002, 2009 | 4 | * Copyright IBM Corp. 2002, 2012 |
5 | * | 5 | * |
6 | * Author(s): Arnd Bergmann (arndb@de.ibm.com) | 6 | * Author(s): Arnd Bergmann (arndb@de.ibm.com) |
7 | * Cornelia Huck (cornelia.huck@de.ibm.com) | 7 | * Cornelia Huck (cornelia.huck@de.ibm.com) |
@@ -15,10 +15,13 @@ | |||
15 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
16 | #include <linux/dcache.h> | 16 | #include <linux/dcache.h> |
17 | 17 | ||
18 | #include <asm/cio.h> | ||
18 | #include <asm/ccwdev.h> | 19 | #include <asm/ccwdev.h> |
19 | #include <asm/ccwgroup.h> | 20 | #include <asm/ccwgroup.h> |
20 | 21 | ||
21 | #define CCW_BUS_ID_SIZE 20 | 22 | #include "device.h" |
23 | |||
24 | #define CCW_BUS_ID_SIZE 10 | ||
22 | 25 | ||
23 | /* In Linux 2.4, we had a channel device layer called "chandev" | 26 | /* In Linux 2.4, we had a channel device layer called "chandev" |
24 | * that did all sorts of obscure stuff for networking devices. | 27 | * that did all sorts of obscure stuff for networking devices. |
@@ -27,19 +30,6 @@ | |||
27 | * to devices that use multiple subchannels. | 30 | * to devices that use multiple subchannels. |
28 | */ | 31 | */ |
29 | 32 | ||
30 | /* a device matches a driver if all its slave devices match the same | ||
31 | * entry of the driver */ | ||
32 | static int ccwgroup_bus_match(struct device *dev, struct device_driver * drv) | ||
33 | { | ||
34 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | ||
35 | struct ccwgroup_driver *gdrv = to_ccwgroupdrv(drv); | ||
36 | |||
37 | if (gdev->creator_id == gdrv->driver_id) | ||
38 | return 1; | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static struct bus_type ccwgroup_bus_type; | 33 | static struct bus_type ccwgroup_bus_type; |
44 | 34 | ||
45 | static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) | 35 | static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) |
@@ -254,9 +244,10 @@ static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev) | |||
254 | return 0; | 244 | return 0; |
255 | } | 245 | } |
256 | 246 | ||
257 | static int __get_next_bus_id(const char **buf, char *bus_id) | 247 | static int __get_next_id(const char **buf, struct ccw_dev_id *id) |
258 | { | 248 | { |
259 | int rc, len; | 249 | unsigned int cssid, ssid, devno; |
250 | int ret = 0, len; | ||
260 | char *start, *end; | 251 | char *start, *end; |
261 | 252 | ||
262 | start = (char *)*buf; | 253 | start = (char *)*buf; |
@@ -271,49 +262,40 @@ static int __get_next_bus_id(const char **buf, char *bus_id) | |||
271 | len = end - start + 1; | 262 | len = end - start + 1; |
272 | end++; | 263 | end++; |
273 | } | 264 | } |
274 | if (len < CCW_BUS_ID_SIZE) { | 265 | if (len <= CCW_BUS_ID_SIZE) { |
275 | strlcpy(bus_id, start, len); | 266 | if (sscanf(start, "%2x.%1x.%04x", &cssid, &ssid, &devno) != 3) |
276 | rc = 0; | 267 | ret = -EINVAL; |
277 | } else | 268 | } else |
278 | rc = -EINVAL; | 269 | ret = -EINVAL; |
279 | *buf = end; | ||
280 | return rc; | ||
281 | } | ||
282 | |||
283 | static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE]) | ||
284 | { | ||
285 | int cssid, ssid, devno; | ||
286 | 270 | ||
287 | /* Must be of form %x.%x.%04x */ | 271 | if (!ret) { |
288 | if (sscanf(bus_id, "%x.%1x.%04x", &cssid, &ssid, &devno) != 3) | 272 | id->ssid = ssid; |
289 | return 0; | 273 | id->devno = devno; |
290 | return 1; | 274 | } |
275 | *buf = end; | ||
276 | return ret; | ||
291 | } | 277 | } |
292 | 278 | ||
293 | /** | 279 | /** |
294 | * ccwgroup_create_from_string() - create and register a ccw group device | 280 | * ccwgroup_create_dev() - create and register a ccw group device |
295 | * @root: parent device for the new device | 281 | * @parent: parent device for the new device |
296 | * @creator_id: identifier of creating driver | 282 | * @gdrv: driver for the new group device |
297 | * @cdrv: ccw driver of slave devices | ||
298 | * @num_devices: number of slave devices | 283 | * @num_devices: number of slave devices |
299 | * @buf: buffer containing comma separated bus ids of slave devices | 284 | * @buf: buffer containing comma separated bus ids of slave devices |
300 | * | 285 | * |
301 | * Create and register a new ccw group device as a child of @root. Slave | 286 | * Create and register a new ccw group device as a child of @parent. Slave |
302 | * devices are obtained from the list of bus ids given in @buf and must all | 287 | * devices are obtained from the list of bus ids given in @buf. |
303 | * belong to @cdrv. | ||
304 | * Returns: | 288 | * Returns: |
305 | * %0 on success and an error code on failure. | 289 | * %0 on success and an error code on failure. |
306 | * Context: | 290 | * Context: |
307 | * non-atomic | 291 | * non-atomic |
308 | */ | 292 | */ |
309 | int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, | 293 | int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, |
310 | struct ccw_driver *cdrv, int num_devices, | 294 | int num_devices, const char *buf) |
311 | const char *buf) | ||
312 | { | 295 | { |
313 | struct ccwgroup_device *gdev; | 296 | struct ccwgroup_device *gdev; |
297 | struct ccw_dev_id dev_id; | ||
314 | int rc, i; | 298 | int rc, i; |
315 | char tmp_bus_id[CCW_BUS_ID_SIZE]; | ||
316 | const char *curr_buf; | ||
317 | 299 | ||
318 | gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]), | 300 | gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]), |
319 | GFP_KERNEL); | 301 | GFP_KERNEL); |
@@ -323,29 +305,24 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, | |||
323 | atomic_set(&gdev->onoff, 0); | 305 | atomic_set(&gdev->onoff, 0); |
324 | mutex_init(&gdev->reg_mutex); | 306 | mutex_init(&gdev->reg_mutex); |
325 | mutex_lock(&gdev->reg_mutex); | 307 | mutex_lock(&gdev->reg_mutex); |
326 | gdev->creator_id = creator_id; | ||
327 | gdev->count = num_devices; | 308 | gdev->count = num_devices; |
328 | gdev->dev.bus = &ccwgroup_bus_type; | 309 | gdev->dev.bus = &ccwgroup_bus_type; |
329 | gdev->dev.parent = root; | 310 | gdev->dev.parent = parent; |
330 | gdev->dev.release = ccwgroup_release; | 311 | gdev->dev.release = ccwgroup_release; |
331 | device_initialize(&gdev->dev); | 312 | device_initialize(&gdev->dev); |
332 | 313 | ||
333 | curr_buf = buf; | 314 | for (i = 0; i < num_devices && buf; i++) { |
334 | for (i = 0; i < num_devices && curr_buf; i++) { | 315 | rc = __get_next_id(&buf, &dev_id); |
335 | rc = __get_next_bus_id(&curr_buf, tmp_bus_id); | ||
336 | if (rc != 0) | 316 | if (rc != 0) |
337 | goto error; | 317 | goto error; |
338 | if (!__is_valid_bus_id(tmp_bus_id)) { | 318 | gdev->cdev[i] = get_ccwdev_by_dev_id(&dev_id); |
339 | rc = -EINVAL; | ||
340 | goto error; | ||
341 | } | ||
342 | gdev->cdev[i] = get_ccwdev_by_busid(cdrv, tmp_bus_id); | ||
343 | /* | 319 | /* |
344 | * All devices have to be of the same type in | 320 | * All devices have to be of the same type in |
345 | * order to be grouped. | 321 | * order to be grouped. |
346 | */ | 322 | */ |
347 | if (!gdev->cdev[i] | 323 | if (!gdev->cdev[i] || !gdev->cdev[i]->drv || |
348 | || gdev->cdev[i]->id.driver_info != | 324 | gdev->cdev[i]->drv != gdev->cdev[0]->drv || |
325 | gdev->cdev[i]->id.driver_info != | ||
349 | gdev->cdev[0]->id.driver_info) { | 326 | gdev->cdev[0]->id.driver_info) { |
350 | rc = -EINVAL; | 327 | rc = -EINVAL; |
351 | goto error; | 328 | goto error; |
@@ -361,18 +338,25 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, | |||
361 | spin_unlock_irq(gdev->cdev[i]->ccwlock); | 338 | spin_unlock_irq(gdev->cdev[i]->ccwlock); |
362 | } | 339 | } |
363 | /* Check for sufficient number of bus ids. */ | 340 | /* Check for sufficient number of bus ids. */ |
364 | if (i < num_devices && !curr_buf) { | 341 | if (i < num_devices) { |
365 | rc = -EINVAL; | 342 | rc = -EINVAL; |
366 | goto error; | 343 | goto error; |
367 | } | 344 | } |
368 | /* Check for trailing stuff. */ | 345 | /* Check for trailing stuff. */ |
369 | if (i == num_devices && strlen(curr_buf) > 0) { | 346 | if (i == num_devices && strlen(buf) > 0) { |
370 | rc = -EINVAL; | 347 | rc = -EINVAL; |
371 | goto error; | 348 | goto error; |
372 | } | 349 | } |
373 | 350 | ||
374 | dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); | 351 | dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); |
375 | gdev->dev.groups = ccwgroup_attr_groups; | 352 | gdev->dev.groups = ccwgroup_attr_groups; |
353 | |||
354 | if (gdrv) { | ||
355 | gdev->dev.driver = &gdrv->driver; | ||
356 | rc = gdrv->setup ? gdrv->setup(gdev) : 0; | ||
357 | if (rc) | ||
358 | goto error; | ||
359 | } | ||
376 | rc = device_add(&gdev->dev); | 360 | rc = device_add(&gdev->dev); |
377 | if (rc) | 361 | if (rc) |
378 | goto error; | 362 | goto error; |
@@ -397,7 +381,7 @@ error: | |||
397 | put_device(&gdev->dev); | 381 | put_device(&gdev->dev); |
398 | return rc; | 382 | return rc; |
399 | } | 383 | } |
400 | EXPORT_SYMBOL(ccwgroup_create_from_string); | 384 | EXPORT_SYMBOL(ccwgroup_create_dev); |
401 | 385 | ||
402 | static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, | 386 | static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, |
403 | void *data) | 387 | void *data) |
@@ -440,14 +424,6 @@ module_exit(cleanup_ccwgroup); | |||
440 | 424 | ||
441 | /************************** driver stuff ******************************/ | 425 | /************************** driver stuff ******************************/ |
442 | 426 | ||
443 | static int ccwgroup_probe(struct device *dev) | ||
444 | { | ||
445 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | ||
446 | struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver); | ||
447 | |||
448 | return gdrv->probe ? gdrv->probe(gdev) : -ENODEV; | ||
449 | } | ||
450 | |||
451 | static int ccwgroup_remove(struct device *dev) | 427 | static int ccwgroup_remove(struct device *dev) |
452 | { | 428 | { |
453 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | 429 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
@@ -542,8 +518,6 @@ static const struct dev_pm_ops ccwgroup_pm_ops = { | |||
542 | 518 | ||
543 | static struct bus_type ccwgroup_bus_type = { | 519 | static struct bus_type ccwgroup_bus_type = { |
544 | .name = "ccwgroup", | 520 | .name = "ccwgroup", |
545 | .match = ccwgroup_bus_match, | ||
546 | .probe = ccwgroup_probe, | ||
547 | .remove = ccwgroup_remove, | 521 | .remove = ccwgroup_remove, |
548 | .shutdown = ccwgroup_shutdown, | 522 | .shutdown = ccwgroup_shutdown, |
549 | .pm = &ccwgroup_pm_ops, | 523 | .pm = &ccwgroup_pm_ops, |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index a49c46c91983..a6ddaed8793d 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -656,51 +656,34 @@ static struct io_subchannel_private console_priv; | |||
656 | static int console_subchannel_in_use; | 656 | static int console_subchannel_in_use; |
657 | 657 | ||
658 | /* | 658 | /* |
659 | * Use cio_tpi to get a pending interrupt and call the interrupt handler. | 659 | * Use cio_tsch to update the subchannel status and call the interrupt handler |
660 | * Return non-zero if an interrupt was processed, zero otherwise. | 660 | * if status had been pending. Called with the console_subchannel lock. |
661 | */ | 661 | */ |
662 | static int cio_tpi(void) | 662 | static void cio_tsch(struct subchannel *sch) |
663 | { | 663 | { |
664 | struct tpi_info *tpi_info; | ||
665 | struct subchannel *sch; | ||
666 | struct irb *irb; | 664 | struct irb *irb; |
667 | int irq_context; | 665 | int irq_context; |
668 | 666 | ||
669 | tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id; | ||
670 | if (tpi(NULL) != 1) | ||
671 | return 0; | ||
672 | kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++; | ||
673 | if (tpi_info->adapter_IO) { | ||
674 | do_adapter_IO(tpi_info->isc); | ||
675 | return 1; | ||
676 | } | ||
677 | irb = (struct irb *)&S390_lowcore.irb; | 667 | irb = (struct irb *)&S390_lowcore.irb; |
678 | /* Store interrupt response block to lowcore. */ | 668 | /* Store interrupt response block to lowcore. */ |
679 | if (tsch(tpi_info->schid, irb) != 0) { | 669 | if (tsch(sch->schid, irb) != 0) |
680 | /* Not status pending or not operational. */ | 670 | /* Not status pending or not operational. */ |
681 | kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; | 671 | return; |
682 | return 1; | 672 | memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); |
683 | } | 673 | /* Call interrupt handler with updated status. */ |
684 | sch = (struct subchannel *)(unsigned long)tpi_info->intparm; | ||
685 | if (!sch) { | ||
686 | kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; | ||
687 | return 1; | ||
688 | } | ||
689 | irq_context = in_interrupt(); | 674 | irq_context = in_interrupt(); |
690 | if (!irq_context) | 675 | if (!irq_context) { |
691 | local_bh_disable(); | 676 | local_bh_disable(); |
692 | irq_enter(); | 677 | irq_enter(); |
693 | spin_lock(sch->lock); | 678 | } |
694 | memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); | ||
695 | if (sch->driver && sch->driver->irq) | 679 | if (sch->driver && sch->driver->irq) |
696 | sch->driver->irq(sch); | 680 | sch->driver->irq(sch); |
697 | else | 681 | else |
698 | kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; | 682 | kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; |
699 | spin_unlock(sch->lock); | 683 | if (!irq_context) { |
700 | irq_exit(); | 684 | irq_exit(); |
701 | if (!irq_context) | ||
702 | _local_bh_enable(); | 685 | _local_bh_enable(); |
703 | return 1; | 686 | } |
704 | } | 687 | } |
705 | 688 | ||
706 | void *cio_get_console_priv(void) | 689 | void *cio_get_console_priv(void) |
@@ -712,34 +695,16 @@ void *cio_get_console_priv(void) | |||
712 | * busy wait for the next interrupt on the console | 695 | * busy wait for the next interrupt on the console |
713 | */ | 696 | */ |
714 | void wait_cons_dev(void) | 697 | void wait_cons_dev(void) |
715 | __releases(console_subchannel.lock) | ||
716 | __acquires(console_subchannel.lock) | ||
717 | { | 698 | { |
718 | unsigned long cr6 __attribute__ ((aligned (8))); | ||
719 | unsigned long save_cr6 __attribute__ ((aligned (8))); | ||
720 | |||
721 | /* | ||
722 | * before entering the spinlock we may already have | ||
723 | * processed the interrupt on a different CPU... | ||
724 | */ | ||
725 | if (!console_subchannel_in_use) | 699 | if (!console_subchannel_in_use) |
726 | return; | 700 | return; |
727 | 701 | ||
728 | /* disable all but the console isc */ | 702 | while (1) { |
729 | __ctl_store (save_cr6, 6, 6); | 703 | cio_tsch(&console_subchannel); |
730 | cr6 = 1UL << (31 - CONSOLE_ISC); | 704 | if (console_subchannel.schib.scsw.cmd.actl == 0) |
731 | __ctl_load (cr6, 6, 6); | 705 | break; |
732 | 706 | udelay_simple(100); | |
733 | do { | 707 | } |
734 | spin_unlock(console_subchannel.lock); | ||
735 | if (!cio_tpi()) | ||
736 | cpu_relax(); | ||
737 | spin_lock(console_subchannel.lock); | ||
738 | } while (console_subchannel.schib.scsw.cmd.actl != 0); | ||
739 | /* | ||
740 | * restore previous isc value | ||
741 | */ | ||
742 | __ctl_load (save_cr6, 6, 6); | ||
743 | } | 708 | } |
744 | 709 | ||
745 | static int | 710 | static int |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 02d015259461..f8f952d52045 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -695,7 +695,17 @@ static int match_dev_id(struct device *dev, void *data) | |||
695 | return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); | 695 | return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); |
696 | } | 696 | } |
697 | 697 | ||
698 | static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) | 698 | /** |
699 | * get_ccwdev_by_dev_id() - obtain device from a ccw device id | ||
700 | * @dev_id: id of the device to be searched | ||
701 | * | ||
702 | * This function searches all devices attached to the ccw bus for a device | ||
703 | * matching @dev_id. | ||
704 | * Returns: | ||
705 | * If a device is found its reference count is increased and returned; | ||
706 | * else %NULL is returned. | ||
707 | */ | ||
708 | struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) | ||
699 | { | 709 | { |
700 | struct device *dev; | 710 | struct device *dev; |
701 | 711 | ||
@@ -703,6 +713,7 @@ static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) | |||
703 | 713 | ||
704 | return dev ? to_ccwdev(dev) : NULL; | 714 | return dev ? to_ccwdev(dev) : NULL; |
705 | } | 715 | } |
716 | EXPORT_SYMBOL_GPL(get_ccwdev_by_dev_id); | ||
706 | 717 | ||
707 | static void ccw_device_do_unbind_bind(struct ccw_device *cdev) | 718 | static void ccw_device_do_unbind_bind(struct ccw_device *cdev) |
708 | { | 719 | { |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index 179824b3082f..6bace6942396 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
@@ -101,6 +101,7 @@ int ccw_device_test_sense_data(struct ccw_device *); | |||
101 | void ccw_device_schedule_sch_unregister(struct ccw_device *); | 101 | void ccw_device_schedule_sch_unregister(struct ccw_device *); |
102 | int ccw_purge_blacklisted(void); | 102 | int ccw_purge_blacklisted(void); |
103 | void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo); | 103 | void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo); |
104 | struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id); | ||
104 | 105 | ||
105 | /* Function prototypes for device status and basic sense stuff. */ | 106 | /* Function prototypes for device status and basic sense stuff. */ |
106 | void ccw_device_accumulate_irb(struct ccw_device *, struct irb *); | 107 | void ccw_device_accumulate_irb(struct ccw_device *, struct irb *); |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 35c685c374e9..7493efafa0d5 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -63,7 +63,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask, | |||
63 | " ipm %0\n" | 63 | " ipm %0\n" |
64 | " srl %0,28\n" | 64 | " srl %0,28\n" |
65 | : "=d" (cc) | 65 | : "=d" (cc) |
66 | : "d" (__fc), "d" (__schid), "d" (__mask) : "cc", "memory"); | 66 | : "d" (__fc), "d" (__schid), "d" (__mask) : "cc"); |
67 | return cc; | 67 | return cc; |
68 | } | 68 | } |
69 | 69 | ||
@@ -74,7 +74,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask, | |||
74 | * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer | 74 | * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer |
75 | * @fc: function code to perform | 75 | * @fc: function code to perform |
76 | * | 76 | * |
77 | * Returns cc or QDIO_ERROR_SIGA_ACCESS_EXCEPTION. | 77 | * Returns condition code. |
78 | * Note: For IQDC unicast queues only the highest priority queue is processed. | 78 | * Note: For IQDC unicast queues only the highest priority queue is processed. |
79 | */ | 79 | */ |
80 | static inline int do_siga_output(unsigned long schid, unsigned long mask, | 80 | static inline int do_siga_output(unsigned long schid, unsigned long mask, |
@@ -85,18 +85,16 @@ static inline int do_siga_output(unsigned long schid, unsigned long mask, | |||
85 | register unsigned long __schid asm("1") = schid; | 85 | register unsigned long __schid asm("1") = schid; |
86 | register unsigned long __mask asm("2") = mask; | 86 | register unsigned long __mask asm("2") = mask; |
87 | register unsigned long __aob asm("3") = aob; | 87 | register unsigned long __aob asm("3") = aob; |
88 | int cc = QDIO_ERROR_SIGA_ACCESS_EXCEPTION; | 88 | int cc; |
89 | 89 | ||
90 | asm volatile( | 90 | asm volatile( |
91 | " siga 0\n" | 91 | " siga 0\n" |
92 | "0: ipm %0\n" | 92 | " ipm %0\n" |
93 | " srl %0,28\n" | 93 | " srl %0,28\n" |
94 | "1:\n" | 94 | : "=d" (cc), "+d" (__fc), "+d" (__aob) |
95 | EX_TABLE(0b, 1b) | 95 | : "d" (__schid), "d" (__mask) |
96 | : "+d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask), | 96 | : "cc"); |
97 | "+d" (__aob) | 97 | *bb = __fc >> 31; |
98 | : : "cc", "memory"); | ||
99 | *bb = ((unsigned int) __fc) >> 31; | ||
100 | return cc; | 98 | return cc; |
101 | } | 99 | } |
102 | 100 | ||
@@ -167,7 +165,7 @@ again: | |||
167 | 165 | ||
168 | DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); | 166 | DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); |
169 | DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); | 167 | DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); |
170 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, | 168 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_GET_BUF_STATE, |
171 | q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); | 169 | q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); |
172 | return 0; | 170 | return 0; |
173 | } | 171 | } |
@@ -215,7 +213,7 @@ again: | |||
215 | 213 | ||
216 | DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); | 214 | DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); |
217 | DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); | 215 | DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); |
218 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, | 216 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_SET_BUF_STATE, |
219 | q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); | 217 | q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); |
220 | return 0; | 218 | return 0; |
221 | } | 219 | } |
@@ -313,7 +311,7 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output, | |||
313 | cc = do_siga_sync(schid, output, input, fc); | 311 | cc = do_siga_sync(schid, output, input, fc); |
314 | if (unlikely(cc)) | 312 | if (unlikely(cc)) |
315 | DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc); | 313 | DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc); |
316 | return cc; | 314 | return (cc) ? -EIO : 0; |
317 | } | 315 | } |
318 | 316 | ||
319 | static inline int qdio_siga_sync_q(struct qdio_q *q) | 317 | static inline int qdio_siga_sync_q(struct qdio_q *q) |
@@ -384,7 +382,7 @@ static inline int qdio_siga_input(struct qdio_q *q) | |||
384 | cc = do_siga_input(schid, q->mask, fc); | 382 | cc = do_siga_input(schid, q->mask, fc); |
385 | if (unlikely(cc)) | 383 | if (unlikely(cc)) |
386 | DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc); | 384 | DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc); |
387 | return cc; | 385 | return (cc) ? -EIO : 0; |
388 | } | 386 | } |
389 | 387 | ||
390 | #define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0) | 388 | #define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0) |
@@ -443,7 +441,7 @@ static void process_buffer_error(struct qdio_q *q, int count) | |||
443 | unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : | 441 | unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : |
444 | SLSB_P_OUTPUT_NOT_INIT; | 442 | SLSB_P_OUTPUT_NOT_INIT; |
445 | 443 | ||
446 | q->qdio_error |= QDIO_ERROR_SLSB_STATE; | 444 | q->qdio_error = QDIO_ERROR_SLSB_STATE; |
447 | 445 | ||
448 | /* special handling for no target buffer empty */ | 446 | /* special handling for no target buffer empty */ |
449 | if ((!q->is_input_q && | 447 | if ((!q->is_input_q && |
@@ -519,7 +517,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) | |||
519 | int count, stop; | 517 | int count, stop; |
520 | unsigned char state = 0; | 518 | unsigned char state = 0; |
521 | 519 | ||
522 | q->timestamp = get_clock_fast(); | 520 | q->timestamp = get_clock(); |
523 | 521 | ||
524 | /* | 522 | /* |
525 | * Don't check 128 buffers, as otherwise qdio_inbound_q_moved | 523 | * Don't check 128 buffers, as otherwise qdio_inbound_q_moved |
@@ -575,7 +573,7 @@ static int qdio_inbound_q_moved(struct qdio_q *q) | |||
575 | 573 | ||
576 | bufnr = get_inbound_buffer_frontier(q); | 574 | bufnr = get_inbound_buffer_frontier(q); |
577 | 575 | ||
578 | if ((bufnr != q->last_move) || q->qdio_error) { | 576 | if (bufnr != q->last_move) { |
579 | q->last_move = bufnr; | 577 | q->last_move = bufnr; |
580 | if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR) | 578 | if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR) |
581 | q->u.in.timestamp = get_clock(); | 579 | q->u.in.timestamp = get_clock(); |
@@ -790,7 +788,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q) | |||
790 | int count, stop; | 788 | int count, stop; |
791 | unsigned char state = 0; | 789 | unsigned char state = 0; |
792 | 790 | ||
793 | q->timestamp = get_clock_fast(); | 791 | q->timestamp = get_clock(); |
794 | 792 | ||
795 | if (need_siga_sync(q)) | 793 | if (need_siga_sync(q)) |
796 | if (((queue_type(q) != QDIO_IQDIO_QFMT) && | 794 | if (((queue_type(q) != QDIO_IQDIO_QFMT) && |
@@ -863,7 +861,7 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q) | |||
863 | 861 | ||
864 | bufnr = get_outbound_buffer_frontier(q); | 862 | bufnr = get_outbound_buffer_frontier(q); |
865 | 863 | ||
866 | if ((bufnr != q->last_move) || q->qdio_error) { | 864 | if (bufnr != q->last_move) { |
867 | q->last_move = bufnr; | 865 | q->last_move = bufnr; |
868 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr); | 866 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr); |
869 | return 1; | 867 | return 1; |
@@ -894,13 +892,16 @@ retry: | |||
894 | goto retry; | 892 | goto retry; |
895 | } | 893 | } |
896 | DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr); | 894 | DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr); |
897 | cc |= QDIO_ERROR_SIGA_BUSY; | 895 | cc = -EBUSY; |
898 | } else | 896 | } else { |
899 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr); | 897 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr); |
898 | cc = -ENOBUFS; | ||
899 | } | ||
900 | break; | 900 | break; |
901 | case 1: | 901 | case 1: |
902 | case 3: | 902 | case 3: |
903 | DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); | 903 | DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); |
904 | cc = -EIO; | ||
904 | break; | 905 | break; |
905 | } | 906 | } |
906 | if (retries) { | 907 | if (retries) { |
@@ -1090,7 +1091,7 @@ static void qdio_handle_activate_check(struct ccw_device *cdev, | |||
1090 | } | 1091 | } |
1091 | 1092 | ||
1092 | count = sub_buf(q->first_to_check, q->first_to_kick); | 1093 | count = sub_buf(q->first_to_check, q->first_to_kick); |
1093 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, | 1094 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE, |
1094 | q->nr, q->first_to_kick, count, irq_ptr->int_parm); | 1095 | q->nr, q->first_to_kick, count, irq_ptr->int_parm); |
1095 | no_handler: | 1096 | no_handler: |
1096 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); | 1097 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); |
@@ -1691,7 +1692,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags, | |||
1691 | "do%02x b:%02x c:%02x", callflags, bufnr, count); | 1692 | "do%02x b:%02x c:%02x", callflags, bufnr, count); |
1692 | 1693 | ||
1693 | if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) | 1694 | if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) |
1694 | return -EBUSY; | 1695 | return -EIO; |
1695 | if (!count) | 1696 | if (!count) |
1696 | return 0; | 1697 | return 0; |
1697 | if (callflags & QDIO_FLAG_SYNC_INPUT) | 1698 | if (callflags & QDIO_FLAG_SYNC_INPUT) |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 7e9a72eb2fe0..b987d4619586 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -215,7 +215,7 @@ ap_queue_interruption_control(ap_qid_t qid, void *ind) | |||
215 | register struct ap_queue_status reg1_out asm ("1"); | 215 | register struct ap_queue_status reg1_out asm ("1"); |
216 | register void *reg2 asm ("2") = ind; | 216 | register void *reg2 asm ("2") = ind; |
217 | asm volatile( | 217 | asm volatile( |
218 | ".long 0xb2af0000" /* PQAP(RAPQ) */ | 218 | ".long 0xb2af0000" /* PQAP(AQIC) */ |
219 | : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2) | 219 | : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2) |
220 | : | 220 | : |
221 | : "cc" ); | 221 | : "cc" ); |
@@ -232,7 +232,7 @@ __ap_query_functions(ap_qid_t qid, unsigned int *functions) | |||
232 | register unsigned long reg2 asm ("2"); | 232 | register unsigned long reg2 asm ("2"); |
233 | 233 | ||
234 | asm volatile( | 234 | asm volatile( |
235 | ".long 0xb2af0000\n" | 235 | ".long 0xb2af0000\n" /* PQAP(TAPQ) */ |
236 | "0:\n" | 236 | "0:\n" |
237 | EX_TABLE(0b, 0b) | 237 | EX_TABLE(0b, 0b) |
238 | : "+d" (reg0), "+d" (reg1), "=d" (reg2) | 238 | : "+d" (reg0), "+d" (reg1), "=d" (reg2) |
@@ -391,7 +391,7 @@ __ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length, | |||
391 | reg0 |= 0x400000UL; | 391 | reg0 |= 0x400000UL; |
392 | 392 | ||
393 | asm volatile ( | 393 | asm volatile ( |
394 | "0: .long 0xb2ad0042\n" /* DQAP */ | 394 | "0: .long 0xb2ad0042\n" /* NQAP */ |
395 | " brc 2,0b" | 395 | " brc 2,0b" |
396 | : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3) | 396 | : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3) |
397 | : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg) | 397 | : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg) |
@@ -450,7 +450,7 @@ __ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length) | |||
450 | 450 | ||
451 | 451 | ||
452 | asm volatile( | 452 | asm volatile( |
453 | "0: .long 0xb2ae0064\n" | 453 | "0: .long 0xb2ae0064\n" /* DQAP */ |
454 | " brc 6,0b\n" | 454 | " brc 6,0b\n" |
455 | : "+d" (reg0), "=d" (reg1), "+d" (reg2), | 455 | : "+d" (reg0), "=d" (reg1), "+d" (reg2), |
456 | "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7), | 456 | "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7), |
@@ -836,12 +836,12 @@ static void __ap_flush_queue(struct ap_device *ap_dev) | |||
836 | list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) { | 836 | list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) { |
837 | list_del_init(&ap_msg->list); | 837 | list_del_init(&ap_msg->list); |
838 | ap_dev->pendingq_count--; | 838 | ap_dev->pendingq_count--; |
839 | ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); | 839 | ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); |
840 | } | 840 | } |
841 | list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) { | 841 | list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) { |
842 | list_del_init(&ap_msg->list); | 842 | list_del_init(&ap_msg->list); |
843 | ap_dev->requestq_count--; | 843 | ap_dev->requestq_count--; |
844 | ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); | 844 | ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); |
845 | } | 845 | } |
846 | } | 846 | } |
847 | 847 | ||
@@ -1329,7 +1329,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) | |||
1329 | continue; | 1329 | continue; |
1330 | list_del_init(&ap_msg->list); | 1330 | list_del_init(&ap_msg->list); |
1331 | ap_dev->pendingq_count--; | 1331 | ap_dev->pendingq_count--; |
1332 | ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply); | 1332 | ap_msg->receive(ap_dev, ap_msg, ap_dev->reply); |
1333 | break; | 1333 | break; |
1334 | } | 1334 | } |
1335 | if (ap_dev->queue_count > 0) | 1335 | if (ap_dev->queue_count > 0) |
@@ -1450,10 +1450,10 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms | |||
1450 | return -EBUSY; | 1450 | return -EBUSY; |
1451 | case AP_RESPONSE_REQ_FAC_NOT_INST: | 1451 | case AP_RESPONSE_REQ_FAC_NOT_INST: |
1452 | case AP_RESPONSE_MESSAGE_TOO_BIG: | 1452 | case AP_RESPONSE_MESSAGE_TOO_BIG: |
1453 | ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); | 1453 | ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); |
1454 | return -EINVAL; | 1454 | return -EINVAL; |
1455 | default: /* Device is gone. */ | 1455 | default: /* Device is gone. */ |
1456 | ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); | 1456 | ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); |
1457 | return -ENODEV; | 1457 | return -ENODEV; |
1458 | } | 1458 | } |
1459 | } else { | 1459 | } else { |
@@ -1471,6 +1471,10 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg) | |||
1471 | unsigned long flags; | 1471 | unsigned long flags; |
1472 | int rc; | 1472 | int rc; |
1473 | 1473 | ||
1474 | /* For asynchronous message handling a valid receive-callback | ||
1475 | * is required. */ | ||
1476 | BUG_ON(!ap_msg->receive); | ||
1477 | |||
1474 | spin_lock_bh(&ap_dev->lock); | 1478 | spin_lock_bh(&ap_dev->lock); |
1475 | if (!ap_dev->unregistered) { | 1479 | if (!ap_dev->unregistered) { |
1476 | /* Make room on the queue by polling for finished requests. */ | 1480 | /* Make room on the queue by polling for finished requests. */ |
@@ -1482,7 +1486,7 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg) | |||
1482 | if (rc == -ENODEV) | 1486 | if (rc == -ENODEV) |
1483 | ap_dev->unregistered = 1; | 1487 | ap_dev->unregistered = 1; |
1484 | } else { | 1488 | } else { |
1485 | ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); | 1489 | ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); |
1486 | rc = -ENODEV; | 1490 | rc = -ENODEV; |
1487 | } | 1491 | } |
1488 | spin_unlock_bh(&ap_dev->lock); | 1492 | spin_unlock_bh(&ap_dev->lock); |
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index d960a6309eec..726fc65809d8 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h | |||
@@ -136,9 +136,6 @@ struct ap_driver { | |||
136 | 136 | ||
137 | int (*probe)(struct ap_device *); | 137 | int (*probe)(struct ap_device *); |
138 | void (*remove)(struct ap_device *); | 138 | void (*remove)(struct ap_device *); |
139 | /* receive is called from tasklet context */ | ||
140 | void (*receive)(struct ap_device *, struct ap_message *, | ||
141 | struct ap_message *); | ||
142 | int request_timeout; /* request timeout in jiffies */ | 139 | int request_timeout; /* request timeout in jiffies */ |
143 | }; | 140 | }; |
144 | 141 | ||
@@ -183,6 +180,9 @@ struct ap_message { | |||
183 | 180 | ||
184 | void *private; /* ap driver private pointer. */ | 181 | void *private; /* ap driver private pointer. */ |
185 | unsigned int special:1; /* Used for special commands. */ | 182 | unsigned int special:1; /* Used for special commands. */ |
183 | /* receive is called from tasklet context */ | ||
184 | void (*receive)(struct ap_device *, struct ap_message *, | ||
185 | struct ap_message *); | ||
186 | }; | 186 | }; |
187 | 187 | ||
188 | #define AP_DEVICE(dt) \ | 188 | #define AP_DEVICE(dt) \ |
@@ -199,6 +199,7 @@ static inline void ap_init_message(struct ap_message *ap_msg) | |||
199 | ap_msg->psmid = 0; | 199 | ap_msg->psmid = 0; |
200 | ap_msg->length = 0; | 200 | ap_msg->length = 0; |
201 | ap_msg->special = 0; | 201 | ap_msg->special = 0; |
202 | ap_msg->receive = NULL; | ||
202 | } | 203 | } |
203 | 204 | ||
204 | /* | 205 | /* |
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index 084286728166..46812440425a 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c | |||
@@ -77,7 +77,6 @@ static void zcrypt_cex2a_receive(struct ap_device *, struct ap_message *, | |||
77 | static struct ap_driver zcrypt_cex2a_driver = { | 77 | static struct ap_driver zcrypt_cex2a_driver = { |
78 | .probe = zcrypt_cex2a_probe, | 78 | .probe = zcrypt_cex2a_probe, |
79 | .remove = zcrypt_cex2a_remove, | 79 | .remove = zcrypt_cex2a_remove, |
80 | .receive = zcrypt_cex2a_receive, | ||
81 | .ids = zcrypt_cex2a_ids, | 80 | .ids = zcrypt_cex2a_ids, |
82 | .request_timeout = CEX2A_CLEANUP_TIME, | 81 | .request_timeout = CEX2A_CLEANUP_TIME, |
83 | }; | 82 | }; |
@@ -349,6 +348,7 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev, | |||
349 | ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); | 348 | ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); |
350 | if (!ap_msg.message) | 349 | if (!ap_msg.message) |
351 | return -ENOMEM; | 350 | return -ENOMEM; |
351 | ap_msg.receive = zcrypt_cex2a_receive; | ||
352 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 352 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
353 | atomic_inc_return(&zcrypt_step); | 353 | atomic_inc_return(&zcrypt_step); |
354 | ap_msg.private = &work; | 354 | ap_msg.private = &work; |
@@ -390,6 +390,7 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev, | |||
390 | ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); | 390 | ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); |
391 | if (!ap_msg.message) | 391 | if (!ap_msg.message) |
392 | return -ENOMEM; | 392 | return -ENOMEM; |
393 | ap_msg.receive = zcrypt_cex2a_receive; | ||
393 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 394 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
394 | atomic_inc_return(&zcrypt_step); | 395 | atomic_inc_return(&zcrypt_step); |
395 | ap_msg.private = &work; | 396 | ap_msg.private = &work; |
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index 0effca925451..ad7951c21b79 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c | |||
@@ -67,7 +67,6 @@ static void zcrypt_pcica_receive(struct ap_device *, struct ap_message *, | |||
67 | static struct ap_driver zcrypt_pcica_driver = { | 67 | static struct ap_driver zcrypt_pcica_driver = { |
68 | .probe = zcrypt_pcica_probe, | 68 | .probe = zcrypt_pcica_probe, |
69 | .remove = zcrypt_pcica_remove, | 69 | .remove = zcrypt_pcica_remove, |
70 | .receive = zcrypt_pcica_receive, | ||
71 | .ids = zcrypt_pcica_ids, | 70 | .ids = zcrypt_pcica_ids, |
72 | .request_timeout = PCICA_CLEANUP_TIME, | 71 | .request_timeout = PCICA_CLEANUP_TIME, |
73 | }; | 72 | }; |
@@ -284,6 +283,7 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev, | |||
284 | ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); | 283 | ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); |
285 | if (!ap_msg.message) | 284 | if (!ap_msg.message) |
286 | return -ENOMEM; | 285 | return -ENOMEM; |
286 | ap_msg.receive = zcrypt_pcica_receive; | ||
287 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 287 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
288 | atomic_inc_return(&zcrypt_step); | 288 | atomic_inc_return(&zcrypt_step); |
289 | ap_msg.private = &work; | 289 | ap_msg.private = &work; |
@@ -322,6 +322,7 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev, | |||
322 | ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); | 322 | ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); |
323 | if (!ap_msg.message) | 323 | if (!ap_msg.message) |
324 | return -ENOMEM; | 324 | return -ENOMEM; |
325 | ap_msg.receive = zcrypt_pcica_receive; | ||
325 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 326 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
326 | atomic_inc_return(&zcrypt_step); | 327 | atomic_inc_return(&zcrypt_step); |
327 | ap_msg.private = &work; | 328 | ap_msg.private = &work; |
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index f9523c0cc8d2..e5dd335fda53 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c | |||
@@ -79,7 +79,6 @@ static void zcrypt_pcicc_receive(struct ap_device *, struct ap_message *, | |||
79 | static struct ap_driver zcrypt_pcicc_driver = { | 79 | static struct ap_driver zcrypt_pcicc_driver = { |
80 | .probe = zcrypt_pcicc_probe, | 80 | .probe = zcrypt_pcicc_probe, |
81 | .remove = zcrypt_pcicc_remove, | 81 | .remove = zcrypt_pcicc_remove, |
82 | .receive = zcrypt_pcicc_receive, | ||
83 | .ids = zcrypt_pcicc_ids, | 82 | .ids = zcrypt_pcicc_ids, |
84 | .request_timeout = PCICC_CLEANUP_TIME, | 83 | .request_timeout = PCICC_CLEANUP_TIME, |
85 | }; | 84 | }; |
@@ -488,6 +487,7 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev, | |||
488 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); | 487 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); |
489 | if (!ap_msg.message) | 488 | if (!ap_msg.message) |
490 | return -ENOMEM; | 489 | return -ENOMEM; |
490 | ap_msg.receive = zcrypt_pcicc_receive; | ||
491 | ap_msg.length = PAGE_SIZE; | 491 | ap_msg.length = PAGE_SIZE; |
492 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 492 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
493 | atomic_inc_return(&zcrypt_step); | 493 | atomic_inc_return(&zcrypt_step); |
@@ -527,6 +527,7 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev, | |||
527 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); | 527 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); |
528 | if (!ap_msg.message) | 528 | if (!ap_msg.message) |
529 | return -ENOMEM; | 529 | return -ENOMEM; |
530 | ap_msg.receive = zcrypt_pcicc_receive; | ||
530 | ap_msg.length = PAGE_SIZE; | 531 | ap_msg.length = PAGE_SIZE; |
531 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 532 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
532 | atomic_inc_return(&zcrypt_step); | 533 | atomic_inc_return(&zcrypt_step); |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index cf1cbd4747f4..f7cc43401816 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
@@ -89,7 +89,6 @@ static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *, | |||
89 | static struct ap_driver zcrypt_pcixcc_driver = { | 89 | static struct ap_driver zcrypt_pcixcc_driver = { |
90 | .probe = zcrypt_pcixcc_probe, | 90 | .probe = zcrypt_pcixcc_probe, |
91 | .remove = zcrypt_pcixcc_remove, | 91 | .remove = zcrypt_pcixcc_remove, |
92 | .receive = zcrypt_pcixcc_receive, | ||
93 | .ids = zcrypt_pcixcc_ids, | 92 | .ids = zcrypt_pcixcc_ids, |
94 | .request_timeout = PCIXCC_CLEANUP_TIME, | 93 | .request_timeout = PCIXCC_CLEANUP_TIME, |
95 | }; | 94 | }; |
@@ -698,6 +697,7 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev, | |||
698 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); | 697 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); |
699 | if (!ap_msg.message) | 698 | if (!ap_msg.message) |
700 | return -ENOMEM; | 699 | return -ENOMEM; |
700 | ap_msg.receive = zcrypt_pcixcc_receive; | ||
701 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 701 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
702 | atomic_inc_return(&zcrypt_step); | 702 | atomic_inc_return(&zcrypt_step); |
703 | ap_msg.private = &resp_type; | 703 | ap_msg.private = &resp_type; |
@@ -738,6 +738,7 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev, | |||
738 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); | 738 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); |
739 | if (!ap_msg.message) | 739 | if (!ap_msg.message) |
740 | return -ENOMEM; | 740 | return -ENOMEM; |
741 | ap_msg.receive = zcrypt_pcixcc_receive; | ||
741 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 742 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
742 | atomic_inc_return(&zcrypt_step); | 743 | atomic_inc_return(&zcrypt_step); |
743 | ap_msg.private = &resp_type; | 744 | ap_msg.private = &resp_type; |
@@ -778,6 +779,7 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, | |||
778 | ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); | 779 | ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); |
779 | if (!ap_msg.message) | 780 | if (!ap_msg.message) |
780 | return -ENOMEM; | 781 | return -ENOMEM; |
782 | ap_msg.receive = zcrypt_pcixcc_receive; | ||
781 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 783 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
782 | atomic_inc_return(&zcrypt_step); | 784 | atomic_inc_return(&zcrypt_step); |
783 | ap_msg.private = &resp_type; | 785 | ap_msg.private = &resp_type; |
@@ -818,6 +820,7 @@ static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev, | |||
818 | ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); | 820 | ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); |
819 | if (!ap_msg.message) | 821 | if (!ap_msg.message) |
820 | return -ENOMEM; | 822 | return -ENOMEM; |
823 | ap_msg.receive = zcrypt_pcixcc_receive; | ||
821 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | 824 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + |
822 | atomic_inc_return(&zcrypt_step); | 825 | atomic_inc_return(&zcrypt_step); |
823 | ap_msg.private = &resp_type; | 826 | ap_msg.private = &resp_type; |
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index b41fae37d3af..6b1ff90d2f00 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c | |||
@@ -136,7 +136,6 @@ static inline void | |||
136 | claw_set_busy(struct net_device *dev) | 136 | claw_set_busy(struct net_device *dev) |
137 | { | 137 | { |
138 | ((struct claw_privbk *)dev->ml_priv)->tbusy = 1; | 138 | ((struct claw_privbk *)dev->ml_priv)->tbusy = 1; |
139 | eieio(); | ||
140 | } | 139 | } |
141 | 140 | ||
142 | static inline void | 141 | static inline void |
@@ -144,13 +143,11 @@ claw_clear_busy(struct net_device *dev) | |||
144 | { | 143 | { |
145 | clear_bit(0, &(((struct claw_privbk *) dev->ml_priv)->tbusy)); | 144 | clear_bit(0, &(((struct claw_privbk *) dev->ml_priv)->tbusy)); |
146 | netif_wake_queue(dev); | 145 | netif_wake_queue(dev); |
147 | eieio(); | ||
148 | } | 146 | } |
149 | 147 | ||
150 | static inline int | 148 | static inline int |
151 | claw_check_busy(struct net_device *dev) | 149 | claw_check_busy(struct net_device *dev) |
152 | { | 150 | { |
153 | eieio(); | ||
154 | return ((struct claw_privbk *) dev->ml_priv)->tbusy; | 151 | return ((struct claw_privbk *) dev->ml_priv)->tbusy; |
155 | } | 152 | } |
156 | 153 | ||
@@ -233,8 +230,6 @@ static ssize_t claw_rbuff_show(struct device *dev, | |||
233 | static ssize_t claw_rbuff_write(struct device *dev, | 230 | static ssize_t claw_rbuff_write(struct device *dev, |
234 | struct device_attribute *attr, | 231 | struct device_attribute *attr, |
235 | const char *buf, size_t count); | 232 | const char *buf, size_t count); |
236 | static int claw_add_files(struct device *dev); | ||
237 | static void claw_remove_files(struct device *dev); | ||
238 | 233 | ||
239 | /* Functions for System Validate */ | 234 | /* Functions for System Validate */ |
240 | static int claw_process_control( struct net_device *dev, struct ccwbk * p_ccw); | 235 | static int claw_process_control( struct net_device *dev, struct ccwbk * p_ccw); |
@@ -267,12 +262,10 @@ static struct ccwgroup_driver claw_group_driver = { | |||
267 | .owner = THIS_MODULE, | 262 | .owner = THIS_MODULE, |
268 | .name = "claw", | 263 | .name = "claw", |
269 | }, | 264 | }, |
270 | .max_slaves = 2, | 265 | .setup = claw_probe, |
271 | .driver_id = 0xC3D3C1E6, | 266 | .remove = claw_remove_device, |
272 | .probe = claw_probe, | 267 | .set_online = claw_new_device, |
273 | .remove = claw_remove_device, | 268 | .set_offline = claw_shutdown_device, |
274 | .set_online = claw_new_device, | ||
275 | .set_offline = claw_shutdown_device, | ||
276 | .prepare = claw_pm_prepare, | 269 | .prepare = claw_pm_prepare, |
277 | }; | 270 | }; |
278 | 271 | ||
@@ -293,30 +286,24 @@ static struct ccw_driver claw_ccw_driver = { | |||
293 | .int_class = IOINT_CLW, | 286 | .int_class = IOINT_CLW, |
294 | }; | 287 | }; |
295 | 288 | ||
296 | static ssize_t | 289 | static ssize_t claw_driver_group_store(struct device_driver *ddrv, |
297 | claw_driver_group_store(struct device_driver *ddrv, const char *buf, | 290 | const char *buf, size_t count) |
298 | size_t count) | ||
299 | { | 291 | { |
300 | int err; | 292 | int err; |
301 | err = ccwgroup_create_from_string(claw_root_dev, | 293 | err = ccwgroup_create_dev(claw_root_dev, &claw_group_driver, 2, buf); |
302 | claw_group_driver.driver_id, | ||
303 | &claw_ccw_driver, 2, buf); | ||
304 | return err ? err : count; | 294 | return err ? err : count; |
305 | } | 295 | } |
306 | |||
307 | static DRIVER_ATTR(group, 0200, NULL, claw_driver_group_store); | 296 | static DRIVER_ATTR(group, 0200, NULL, claw_driver_group_store); |
308 | 297 | ||
309 | static struct attribute *claw_group_attrs[] = { | 298 | static struct attribute *claw_drv_attrs[] = { |
310 | &driver_attr_group.attr, | 299 | &driver_attr_group.attr, |
311 | NULL, | 300 | NULL, |
312 | }; | 301 | }; |
313 | 302 | static struct attribute_group claw_drv_attr_group = { | |
314 | static struct attribute_group claw_group_attr_group = { | 303 | .attrs = claw_drv_attrs, |
315 | .attrs = claw_group_attrs, | ||
316 | }; | 304 | }; |
317 | 305 | static const struct attribute_group *claw_drv_attr_groups[] = { | |
318 | static const struct attribute_group *claw_group_attr_groups[] = { | 306 | &claw_drv_attr_group, |
319 | &claw_group_attr_group, | ||
320 | NULL, | 307 | NULL, |
321 | }; | 308 | }; |
322 | 309 | ||
@@ -324,60 +311,6 @@ static const struct attribute_group *claw_group_attr_groups[] = { | |||
324 | * Key functions | 311 | * Key functions |
325 | */ | 312 | */ |
326 | 313 | ||
327 | /*----------------------------------------------------------------* | ||
328 | * claw_probe * | ||
329 | * this function is called for each CLAW device. * | ||
330 | *----------------------------------------------------------------*/ | ||
331 | static int | ||
332 | claw_probe(struct ccwgroup_device *cgdev) | ||
333 | { | ||
334 | int rc; | ||
335 | struct claw_privbk *privptr=NULL; | ||
336 | |||
337 | CLAW_DBF_TEXT(2, setup, "probe"); | ||
338 | if (!get_device(&cgdev->dev)) | ||
339 | return -ENODEV; | ||
340 | privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL); | ||
341 | dev_set_drvdata(&cgdev->dev, privptr); | ||
342 | if (privptr == NULL) { | ||
343 | probe_error(cgdev); | ||
344 | put_device(&cgdev->dev); | ||
345 | CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); | ||
346 | return -ENOMEM; | ||
347 | } | ||
348 | privptr->p_mtc_envelope= kzalloc( MAX_ENVELOPE_SIZE, GFP_KERNEL); | ||
349 | privptr->p_env = kzalloc(sizeof(struct claw_env), GFP_KERNEL); | ||
350 | if ((privptr->p_mtc_envelope==NULL) || (privptr->p_env==NULL)) { | ||
351 | probe_error(cgdev); | ||
352 | put_device(&cgdev->dev); | ||
353 | CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); | ||
354 | return -ENOMEM; | ||
355 | } | ||
356 | memcpy(privptr->p_env->adapter_name,WS_NAME_NOT_DEF,8); | ||
357 | memcpy(privptr->p_env->host_name,WS_NAME_NOT_DEF,8); | ||
358 | memcpy(privptr->p_env->api_type,WS_NAME_NOT_DEF,8); | ||
359 | privptr->p_env->packing = 0; | ||
360 | privptr->p_env->write_buffers = 5; | ||
361 | privptr->p_env->read_buffers = 5; | ||
362 | privptr->p_env->read_size = CLAW_FRAME_SIZE; | ||
363 | privptr->p_env->write_size = CLAW_FRAME_SIZE; | ||
364 | rc = claw_add_files(&cgdev->dev); | ||
365 | if (rc) { | ||
366 | probe_error(cgdev); | ||
367 | put_device(&cgdev->dev); | ||
368 | dev_err(&cgdev->dev, "Creating the /proc files for a new" | ||
369 | " CLAW device failed\n"); | ||
370 | CLAW_DBF_TEXT_(2, setup, "probex%d", rc); | ||
371 | return rc; | ||
372 | } | ||
373 | privptr->p_env->p_priv = privptr; | ||
374 | cgdev->cdev[0]->handler = claw_irq_handler; | ||
375 | cgdev->cdev[1]->handler = claw_irq_handler; | ||
376 | CLAW_DBF_TEXT(2, setup, "prbext 0"); | ||
377 | |||
378 | return 0; | ||
379 | } /* end of claw_probe */ | ||
380 | |||
381 | /*-------------------------------------------------------------------* | 314 | /*-------------------------------------------------------------------* |
382 | * claw_tx * | 315 | * claw_tx * |
383 | *-------------------------------------------------------------------*/ | 316 | *-------------------------------------------------------------------*/ |
@@ -3093,7 +3026,6 @@ claw_remove_device(struct ccwgroup_device *cgdev) | |||
3093 | dev_info(&cgdev->dev, " will be removed.\n"); | 3026 | dev_info(&cgdev->dev, " will be removed.\n"); |
3094 | if (cgdev->state == CCWGROUP_ONLINE) | 3027 | if (cgdev->state == CCWGROUP_ONLINE) |
3095 | claw_shutdown_device(cgdev); | 3028 | claw_shutdown_device(cgdev); |
3096 | claw_remove_files(&cgdev->dev); | ||
3097 | kfree(priv->p_mtc_envelope); | 3029 | kfree(priv->p_mtc_envelope); |
3098 | priv->p_mtc_envelope=NULL; | 3030 | priv->p_mtc_envelope=NULL; |
3099 | kfree(priv->p_env); | 3031 | kfree(priv->p_env); |
@@ -3321,7 +3253,6 @@ claw_rbuff_write(struct device *dev, struct device_attribute *attr, | |||
3321 | CLAW_DBF_TEXT_(2, setup, "RB=%d", p_env->read_buffers); | 3253 | CLAW_DBF_TEXT_(2, setup, "RB=%d", p_env->read_buffers); |
3322 | return count; | 3254 | return count; |
3323 | } | 3255 | } |
3324 | |||
3325 | static DEVICE_ATTR(read_buffer, 0644, claw_rbuff_show, claw_rbuff_write); | 3256 | static DEVICE_ATTR(read_buffer, 0644, claw_rbuff_show, claw_rbuff_write); |
3326 | 3257 | ||
3327 | static struct attribute *claw_attr[] = { | 3258 | static struct attribute *claw_attr[] = { |
@@ -3332,40 +3263,73 @@ static struct attribute *claw_attr[] = { | |||
3332 | &dev_attr_host_name.attr, | 3263 | &dev_attr_host_name.attr, |
3333 | NULL, | 3264 | NULL, |
3334 | }; | 3265 | }; |
3335 | |||
3336 | static struct attribute_group claw_attr_group = { | 3266 | static struct attribute_group claw_attr_group = { |
3337 | .attrs = claw_attr, | 3267 | .attrs = claw_attr, |
3338 | }; | 3268 | }; |
3269 | static const struct attribute_group *claw_attr_groups[] = { | ||
3270 | &claw_attr_group, | ||
3271 | NULL, | ||
3272 | }; | ||
3273 | static const struct device_type claw_devtype = { | ||
3274 | .name = "claw", | ||
3275 | .groups = claw_attr_groups, | ||
3276 | }; | ||
3339 | 3277 | ||
3340 | static int | 3278 | /*----------------------------------------------------------------* |
3341 | claw_add_files(struct device *dev) | 3279 | * claw_probe * |
3280 | * this function is called for each CLAW device. * | ||
3281 | *----------------------------------------------------------------*/ | ||
3282 | static int claw_probe(struct ccwgroup_device *cgdev) | ||
3342 | { | 3283 | { |
3343 | CLAW_DBF_TEXT(2, setup, "add_file"); | 3284 | struct claw_privbk *privptr = NULL; |
3344 | return sysfs_create_group(&dev->kobj, &claw_attr_group); | ||
3345 | } | ||
3346 | 3285 | ||
3347 | static void | 3286 | CLAW_DBF_TEXT(2, setup, "probe"); |
3348 | claw_remove_files(struct device *dev) | 3287 | if (!get_device(&cgdev->dev)) |
3349 | { | 3288 | return -ENODEV; |
3350 | CLAW_DBF_TEXT(2, setup, "rem_file"); | 3289 | privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL); |
3351 | sysfs_remove_group(&dev->kobj, &claw_attr_group); | 3290 | dev_set_drvdata(&cgdev->dev, privptr); |
3352 | } | 3291 | if (privptr == NULL) { |
3292 | probe_error(cgdev); | ||
3293 | put_device(&cgdev->dev); | ||
3294 | CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); | ||
3295 | return -ENOMEM; | ||
3296 | } | ||
3297 | privptr->p_mtc_envelope = kzalloc(MAX_ENVELOPE_SIZE, GFP_KERNEL); | ||
3298 | privptr->p_env = kzalloc(sizeof(struct claw_env), GFP_KERNEL); | ||
3299 | if ((privptr->p_mtc_envelope == NULL) || (privptr->p_env == NULL)) { | ||
3300 | probe_error(cgdev); | ||
3301 | put_device(&cgdev->dev); | ||
3302 | CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); | ||
3303 | return -ENOMEM; | ||
3304 | } | ||
3305 | memcpy(privptr->p_env->adapter_name, WS_NAME_NOT_DEF, 8); | ||
3306 | memcpy(privptr->p_env->host_name, WS_NAME_NOT_DEF, 8); | ||
3307 | memcpy(privptr->p_env->api_type, WS_NAME_NOT_DEF, 8); | ||
3308 | privptr->p_env->packing = 0; | ||
3309 | privptr->p_env->write_buffers = 5; | ||
3310 | privptr->p_env->read_buffers = 5; | ||
3311 | privptr->p_env->read_size = CLAW_FRAME_SIZE; | ||
3312 | privptr->p_env->write_size = CLAW_FRAME_SIZE; | ||
3313 | privptr->p_env->p_priv = privptr; | ||
3314 | cgdev->cdev[0]->handler = claw_irq_handler; | ||
3315 | cgdev->cdev[1]->handler = claw_irq_handler; | ||
3316 | cgdev->dev.type = &claw_devtype; | ||
3317 | CLAW_DBF_TEXT(2, setup, "prbext 0"); | ||
3318 | |||
3319 | return 0; | ||
3320 | } /* end of claw_probe */ | ||
3353 | 3321 | ||
3354 | /*--------------------------------------------------------------------* | 3322 | /*--------------------------------------------------------------------* |
3355 | * claw_init and cleanup * | 3323 | * claw_init and cleanup * |
3356 | *---------------------------------------------------------------------*/ | 3324 | *---------------------------------------------------------------------*/ |
3357 | 3325 | ||
3358 | static void __exit | 3326 | static void __exit claw_cleanup(void) |
3359 | claw_cleanup(void) | ||
3360 | { | 3327 | { |
3361 | driver_remove_file(&claw_group_driver.driver, | ||
3362 | &driver_attr_group); | ||
3363 | ccwgroup_driver_unregister(&claw_group_driver); | 3328 | ccwgroup_driver_unregister(&claw_group_driver); |
3364 | ccw_driver_unregister(&claw_ccw_driver); | 3329 | ccw_driver_unregister(&claw_ccw_driver); |
3365 | root_device_unregister(claw_root_dev); | 3330 | root_device_unregister(claw_root_dev); |
3366 | claw_unregister_debug_facility(); | 3331 | claw_unregister_debug_facility(); |
3367 | pr_info("Driver unloaded\n"); | 3332 | pr_info("Driver unloaded\n"); |
3368 | |||
3369 | } | 3333 | } |
3370 | 3334 | ||
3371 | /** | 3335 | /** |
@@ -3374,8 +3338,7 @@ claw_cleanup(void) | |||
3374 | * | 3338 | * |
3375 | * @return 0 on success, !0 on error. | 3339 | * @return 0 on success, !0 on error. |
3376 | */ | 3340 | */ |
3377 | static int __init | 3341 | static int __init claw_init(void) |
3378 | claw_init(void) | ||
3379 | { | 3342 | { |
3380 | int ret = 0; | 3343 | int ret = 0; |
3381 | 3344 | ||
@@ -3394,7 +3357,7 @@ claw_init(void) | |||
3394 | ret = ccw_driver_register(&claw_ccw_driver); | 3357 | ret = ccw_driver_register(&claw_ccw_driver); |
3395 | if (ret) | 3358 | if (ret) |
3396 | goto ccw_err; | 3359 | goto ccw_err; |
3397 | claw_group_driver.driver.groups = claw_group_attr_groups; | 3360 | claw_group_driver.driver.groups = claw_drv_attr_groups; |
3398 | ret = ccwgroup_driver_register(&claw_group_driver); | 3361 | ret = ccwgroup_driver_register(&claw_group_driver); |
3399 | if (ret) | 3362 | if (ret) |
3400 | goto ccwgroup_err; | 3363 | goto ccwgroup_err; |
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 11f3b071f305..3cd25544a27a 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c | |||
@@ -1296,6 +1296,11 @@ static void ctcm_irq_handler(struct ccw_device *cdev, | |||
1296 | 1296 | ||
1297 | } | 1297 | } |
1298 | 1298 | ||
1299 | static const struct device_type ctcm_devtype = { | ||
1300 | .name = "ctcm", | ||
1301 | .groups = ctcm_attr_groups, | ||
1302 | }; | ||
1303 | |||
1299 | /** | 1304 | /** |
1300 | * Add ctcm specific attributes. | 1305 | * Add ctcm specific attributes. |
1301 | * Add ctcm private data. | 1306 | * Add ctcm private data. |
@@ -1307,7 +1312,6 @@ static void ctcm_irq_handler(struct ccw_device *cdev, | |||
1307 | static int ctcm_probe_device(struct ccwgroup_device *cgdev) | 1312 | static int ctcm_probe_device(struct ccwgroup_device *cgdev) |
1308 | { | 1313 | { |
1309 | struct ctcm_priv *priv; | 1314 | struct ctcm_priv *priv; |
1310 | int rc; | ||
1311 | 1315 | ||
1312 | CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, | 1316 | CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, |
1313 | "%s %p", | 1317 | "%s %p", |
@@ -1324,17 +1328,11 @@ static int ctcm_probe_device(struct ccwgroup_device *cgdev) | |||
1324 | put_device(&cgdev->dev); | 1328 | put_device(&cgdev->dev); |
1325 | return -ENOMEM; | 1329 | return -ENOMEM; |
1326 | } | 1330 | } |
1327 | |||
1328 | rc = ctcm_add_files(&cgdev->dev); | ||
1329 | if (rc) { | ||
1330 | kfree(priv); | ||
1331 | put_device(&cgdev->dev); | ||
1332 | return rc; | ||
1333 | } | ||
1334 | priv->buffer_size = CTCM_BUFSIZE_DEFAULT; | 1331 | priv->buffer_size = CTCM_BUFSIZE_DEFAULT; |
1335 | cgdev->cdev[0]->handler = ctcm_irq_handler; | 1332 | cgdev->cdev[0]->handler = ctcm_irq_handler; |
1336 | cgdev->cdev[1]->handler = ctcm_irq_handler; | 1333 | cgdev->cdev[1]->handler = ctcm_irq_handler; |
1337 | dev_set_drvdata(&cgdev->dev, priv); | 1334 | dev_set_drvdata(&cgdev->dev, priv); |
1335 | cgdev->dev.type = &ctcm_devtype; | ||
1338 | 1336 | ||
1339 | return 0; | 1337 | return 0; |
1340 | } | 1338 | } |
@@ -1611,11 +1609,6 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev) | |||
1611 | goto out_dev; | 1609 | goto out_dev; |
1612 | } | 1610 | } |
1613 | 1611 | ||
1614 | if (ctcm_add_attributes(&cgdev->dev)) { | ||
1615 | result = -ENODEV; | ||
1616 | goto out_unregister; | ||
1617 | } | ||
1618 | |||
1619 | strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name)); | 1612 | strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name)); |
1620 | 1613 | ||
1621 | dev_info(&dev->dev, | 1614 | dev_info(&dev->dev, |
@@ -1629,8 +1622,6 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev) | |||
1629 | priv->channel[CTCM_WRITE]->id, priv->protocol); | 1622 | priv->channel[CTCM_WRITE]->id, priv->protocol); |
1630 | 1623 | ||
1631 | return 0; | 1624 | return 0; |
1632 | out_unregister: | ||
1633 | unregister_netdev(dev); | ||
1634 | out_dev: | 1625 | out_dev: |
1635 | ctcm_free_netdevice(dev); | 1626 | ctcm_free_netdevice(dev); |
1636 | out_ccw2: | 1627 | out_ccw2: |
@@ -1669,7 +1660,6 @@ static int ctcm_shutdown_device(struct ccwgroup_device *cgdev) | |||
1669 | /* Close the device */ | 1660 | /* Close the device */ |
1670 | ctcm_close(dev); | 1661 | ctcm_close(dev); |
1671 | dev->flags &= ~IFF_RUNNING; | 1662 | dev->flags &= ~IFF_RUNNING; |
1672 | ctcm_remove_attributes(&cgdev->dev); | ||
1673 | channel_free(priv->channel[CTCM_READ]); | 1663 | channel_free(priv->channel[CTCM_READ]); |
1674 | } else | 1664 | } else |
1675 | dev = NULL; | 1665 | dev = NULL; |
@@ -1711,7 +1701,6 @@ static void ctcm_remove_device(struct ccwgroup_device *cgdev) | |||
1711 | 1701 | ||
1712 | if (cgdev->state == CCWGROUP_ONLINE) | 1702 | if (cgdev->state == CCWGROUP_ONLINE) |
1713 | ctcm_shutdown_device(cgdev); | 1703 | ctcm_shutdown_device(cgdev); |
1714 | ctcm_remove_files(&cgdev->dev); | ||
1715 | dev_set_drvdata(&cgdev->dev, NULL); | 1704 | dev_set_drvdata(&cgdev->dev, NULL); |
1716 | kfree(priv); | 1705 | kfree(priv); |
1717 | put_device(&cgdev->dev); | 1706 | put_device(&cgdev->dev); |
@@ -1778,9 +1767,7 @@ static struct ccwgroup_driver ctcm_group_driver = { | |||
1778 | .owner = THIS_MODULE, | 1767 | .owner = THIS_MODULE, |
1779 | .name = CTC_DRIVER_NAME, | 1768 | .name = CTC_DRIVER_NAME, |
1780 | }, | 1769 | }, |
1781 | .max_slaves = 2, | 1770 | .setup = ctcm_probe_device, |
1782 | .driver_id = 0xC3E3C3D4, /* CTCM */ | ||
1783 | .probe = ctcm_probe_device, | ||
1784 | .remove = ctcm_remove_device, | 1771 | .remove = ctcm_remove_device, |
1785 | .set_online = ctcm_new_device, | 1772 | .set_online = ctcm_new_device, |
1786 | .set_offline = ctcm_shutdown_device, | 1773 | .set_offline = ctcm_shutdown_device, |
@@ -1789,31 +1776,25 @@ static struct ccwgroup_driver ctcm_group_driver = { | |||
1789 | .restore = ctcm_pm_resume, | 1776 | .restore = ctcm_pm_resume, |
1790 | }; | 1777 | }; |
1791 | 1778 | ||
1792 | static ssize_t | 1779 | static ssize_t ctcm_driver_group_store(struct device_driver *ddrv, |
1793 | ctcm_driver_group_store(struct device_driver *ddrv, const char *buf, | 1780 | const char *buf, size_t count) |
1794 | size_t count) | ||
1795 | { | 1781 | { |
1796 | int err; | 1782 | int err; |
1797 | 1783 | ||
1798 | err = ccwgroup_create_from_string(ctcm_root_dev, | 1784 | err = ccwgroup_create_dev(ctcm_root_dev, &ctcm_group_driver, 2, buf); |
1799 | ctcm_group_driver.driver_id, | ||
1800 | &ctcm_ccw_driver, 2, buf); | ||
1801 | return err ? err : count; | 1785 | return err ? err : count; |
1802 | } | 1786 | } |
1803 | |||
1804 | static DRIVER_ATTR(group, 0200, NULL, ctcm_driver_group_store); | 1787 | static DRIVER_ATTR(group, 0200, NULL, ctcm_driver_group_store); |
1805 | 1788 | ||
1806 | static struct attribute *ctcm_group_attrs[] = { | 1789 | static struct attribute *ctcm_drv_attrs[] = { |
1807 | &driver_attr_group.attr, | 1790 | &driver_attr_group.attr, |
1808 | NULL, | 1791 | NULL, |
1809 | }; | 1792 | }; |
1810 | 1793 | static struct attribute_group ctcm_drv_attr_group = { | |
1811 | static struct attribute_group ctcm_group_attr_group = { | 1794 | .attrs = ctcm_drv_attrs, |
1812 | .attrs = ctcm_group_attrs, | ||
1813 | }; | 1795 | }; |
1814 | 1796 | static const struct attribute_group *ctcm_drv_attr_groups[] = { | |
1815 | static const struct attribute_group *ctcm_group_attr_groups[] = { | 1797 | &ctcm_drv_attr_group, |
1816 | &ctcm_group_attr_group, | ||
1817 | NULL, | 1798 | NULL, |
1818 | }; | 1799 | }; |
1819 | 1800 | ||
@@ -1829,7 +1810,6 @@ static const struct attribute_group *ctcm_group_attr_groups[] = { | |||
1829 | */ | 1810 | */ |
1830 | static void __exit ctcm_exit(void) | 1811 | static void __exit ctcm_exit(void) |
1831 | { | 1812 | { |
1832 | driver_remove_file(&ctcm_group_driver.driver, &driver_attr_group); | ||
1833 | ccwgroup_driver_unregister(&ctcm_group_driver); | 1813 | ccwgroup_driver_unregister(&ctcm_group_driver); |
1834 | ccw_driver_unregister(&ctcm_ccw_driver); | 1814 | ccw_driver_unregister(&ctcm_ccw_driver); |
1835 | root_device_unregister(ctcm_root_dev); | 1815 | root_device_unregister(ctcm_root_dev); |
@@ -1867,7 +1847,7 @@ static int __init ctcm_init(void) | |||
1867 | ret = ccw_driver_register(&ctcm_ccw_driver); | 1847 | ret = ccw_driver_register(&ctcm_ccw_driver); |
1868 | if (ret) | 1848 | if (ret) |
1869 | goto ccw_err; | 1849 | goto ccw_err; |
1870 | ctcm_group_driver.driver.groups = ctcm_group_attr_groups; | 1850 | ctcm_group_driver.driver.groups = ctcm_drv_attr_groups; |
1871 | ret = ccwgroup_driver_register(&ctcm_group_driver); | 1851 | ret = ccwgroup_driver_register(&ctcm_group_driver); |
1872 | if (ret) | 1852 | if (ret) |
1873 | goto ccwgroup_err; | 1853 | goto ccwgroup_err; |
diff --git a/drivers/s390/net/ctcm_main.h b/drivers/s390/net/ctcm_main.h index 24d5215eb0c4..b9056a55d995 100644 --- a/drivers/s390/net/ctcm_main.h +++ b/drivers/s390/net/ctcm_main.h | |||
@@ -225,13 +225,7 @@ struct ctcm_priv { | |||
225 | int ctcm_open(struct net_device *dev); | 225 | int ctcm_open(struct net_device *dev); |
226 | int ctcm_close(struct net_device *dev); | 226 | int ctcm_close(struct net_device *dev); |
227 | 227 | ||
228 | /* | 228 | extern const struct attribute_group *ctcm_attr_groups[]; |
229 | * prototypes for non-static sysfs functions | ||
230 | */ | ||
231 | int ctcm_add_attributes(struct device *dev); | ||
232 | void ctcm_remove_attributes(struct device *dev); | ||
233 | int ctcm_add_files(struct device *dev); | ||
234 | void ctcm_remove_files(struct device *dev); | ||
235 | 229 | ||
236 | /* | 230 | /* |
237 | * Compatibility macros for busy handling | 231 | * Compatibility macros for busy handling |
diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c index 650aec1839e9..0c27ae726475 100644 --- a/drivers/s390/net/ctcm_sysfs.c +++ b/drivers/s390/net/ctcm_sysfs.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #define KMSG_COMPONENT "ctcm" | 13 | #define KMSG_COMPONENT "ctcm" |
14 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 14 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
15 | 15 | ||
16 | #include <linux/device.h> | ||
16 | #include <linux/sysfs.h> | 17 | #include <linux/sysfs.h> |
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
18 | #include "ctcm_main.h" | 19 | #include "ctcm_main.h" |
@@ -108,10 +109,12 @@ static void ctcm_print_statistics(struct ctcm_priv *priv) | |||
108 | } | 109 | } |
109 | 110 | ||
110 | static ssize_t stats_show(struct device *dev, | 111 | static ssize_t stats_show(struct device *dev, |
111 | struct device_attribute *attr, char *buf) | 112 | struct device_attribute *attr, char *buf) |
112 | { | 113 | { |
114 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | ||
113 | struct ctcm_priv *priv = dev_get_drvdata(dev); | 115 | struct ctcm_priv *priv = dev_get_drvdata(dev); |
114 | if (!priv) | 116 | |
117 | if (!priv || gdev->state != CCWGROUP_ONLINE) | ||
115 | return -ENODEV; | 118 | return -ENODEV; |
116 | ctcm_print_statistics(priv); | 119 | ctcm_print_statistics(priv); |
117 | return sprintf(buf, "0\n"); | 120 | return sprintf(buf, "0\n"); |
@@ -190,34 +193,14 @@ static struct attribute *ctcm_attr[] = { | |||
190 | &dev_attr_protocol.attr, | 193 | &dev_attr_protocol.attr, |
191 | &dev_attr_type.attr, | 194 | &dev_attr_type.attr, |
192 | &dev_attr_buffer.attr, | 195 | &dev_attr_buffer.attr, |
196 | &dev_attr_stats.attr, | ||
193 | NULL, | 197 | NULL, |
194 | }; | 198 | }; |
195 | 199 | ||
196 | static struct attribute_group ctcm_attr_group = { | 200 | static struct attribute_group ctcm_attr_group = { |
197 | .attrs = ctcm_attr, | 201 | .attrs = ctcm_attr, |
198 | }; | 202 | }; |
199 | 203 | const struct attribute_group *ctcm_attr_groups[] = { | |
200 | int ctcm_add_attributes(struct device *dev) | 204 | &ctcm_attr_group, |
201 | { | 205 | NULL, |
202 | int rc; | 206 | }; |
203 | |||
204 | rc = device_create_file(dev, &dev_attr_stats); | ||
205 | |||
206 | return rc; | ||
207 | } | ||
208 | |||
209 | void ctcm_remove_attributes(struct device *dev) | ||
210 | { | ||
211 | device_remove_file(dev, &dev_attr_stats); | ||
212 | } | ||
213 | |||
214 | int ctcm_add_files(struct device *dev) | ||
215 | { | ||
216 | return sysfs_create_group(&dev->kobj, &ctcm_attr_group); | ||
217 | } | ||
218 | |||
219 | void ctcm_remove_files(struct device *dev) | ||
220 | { | ||
221 | sysfs_remove_group(&dev->kobj, &ctcm_attr_group); | ||
222 | } | ||
223 | |||
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 6056cf6da035..a3adf4b1c60d 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -2040,10 +2040,17 @@ static struct attribute * lcs_attrs[] = { | |||
2040 | &dev_attr_recover.attr, | 2040 | &dev_attr_recover.attr, |
2041 | NULL, | 2041 | NULL, |
2042 | }; | 2042 | }; |
2043 | |||
2044 | static struct attribute_group lcs_attr_group = { | 2043 | static struct attribute_group lcs_attr_group = { |
2045 | .attrs = lcs_attrs, | 2044 | .attrs = lcs_attrs, |
2046 | }; | 2045 | }; |
2046 | static const struct attribute_group *lcs_attr_groups[] = { | ||
2047 | &lcs_attr_group, | ||
2048 | NULL, | ||
2049 | }; | ||
2050 | static const struct device_type lcs_devtype = { | ||
2051 | .name = "lcs", | ||
2052 | .groups = lcs_attr_groups, | ||
2053 | }; | ||
2047 | 2054 | ||
2048 | /** | 2055 | /** |
2049 | * lcs_probe_device is called on establishing a new ccwgroup_device. | 2056 | * lcs_probe_device is called on establishing a new ccwgroup_device. |
@@ -2052,7 +2059,6 @@ static int | |||
2052 | lcs_probe_device(struct ccwgroup_device *ccwgdev) | 2059 | lcs_probe_device(struct ccwgroup_device *ccwgdev) |
2053 | { | 2060 | { |
2054 | struct lcs_card *card; | 2061 | struct lcs_card *card; |
2055 | int ret; | ||
2056 | 2062 | ||
2057 | if (!get_device(&ccwgdev->dev)) | 2063 | if (!get_device(&ccwgdev->dev)) |
2058 | return -ENODEV; | 2064 | return -ENODEV; |
@@ -2064,12 +2070,6 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) | |||
2064 | put_device(&ccwgdev->dev); | 2070 | put_device(&ccwgdev->dev); |
2065 | return -ENOMEM; | 2071 | return -ENOMEM; |
2066 | } | 2072 | } |
2067 | ret = sysfs_create_group(&ccwgdev->dev.kobj, &lcs_attr_group); | ||
2068 | if (ret) { | ||
2069 | lcs_free_card(card); | ||
2070 | put_device(&ccwgdev->dev); | ||
2071 | return ret; | ||
2072 | } | ||
2073 | dev_set_drvdata(&ccwgdev->dev, card); | 2073 | dev_set_drvdata(&ccwgdev->dev, card); |
2074 | ccwgdev->cdev[0]->handler = lcs_irq; | 2074 | ccwgdev->cdev[0]->handler = lcs_irq; |
2075 | ccwgdev->cdev[1]->handler = lcs_irq; | 2075 | ccwgdev->cdev[1]->handler = lcs_irq; |
@@ -2078,7 +2078,9 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) | |||
2078 | card->thread_start_mask = 0; | 2078 | card->thread_start_mask = 0; |
2079 | card->thread_allowed_mask = 0; | 2079 | card->thread_allowed_mask = 0; |
2080 | card->thread_running_mask = 0; | 2080 | card->thread_running_mask = 0; |
2081 | return 0; | 2081 | ccwgdev->dev.type = &lcs_devtype; |
2082 | |||
2083 | return 0; | ||
2082 | } | 2084 | } |
2083 | 2085 | ||
2084 | static int | 2086 | static int |
@@ -2306,9 +2308,9 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev) | |||
2306 | } | 2308 | } |
2307 | if (card->dev) | 2309 | if (card->dev) |
2308 | unregister_netdev(card->dev); | 2310 | unregister_netdev(card->dev); |
2309 | sysfs_remove_group(&ccwgdev->dev.kobj, &lcs_attr_group); | ||
2310 | lcs_cleanup_card(card); | 2311 | lcs_cleanup_card(card); |
2311 | lcs_free_card(card); | 2312 | lcs_free_card(card); |
2313 | dev_set_drvdata(&ccwgdev->dev, NULL); | ||
2312 | put_device(&ccwgdev->dev); | 2314 | put_device(&ccwgdev->dev); |
2313 | } | 2315 | } |
2314 | 2316 | ||
@@ -2393,9 +2395,7 @@ static struct ccwgroup_driver lcs_group_driver = { | |||
2393 | .owner = THIS_MODULE, | 2395 | .owner = THIS_MODULE, |
2394 | .name = "lcs", | 2396 | .name = "lcs", |
2395 | }, | 2397 | }, |
2396 | .max_slaves = 2, | 2398 | .setup = lcs_probe_device, |
2397 | .driver_id = 0xD3C3E2, | ||
2398 | .probe = lcs_probe_device, | ||
2399 | .remove = lcs_remove_device, | 2399 | .remove = lcs_remove_device, |
2400 | .set_online = lcs_new_device, | 2400 | .set_online = lcs_new_device, |
2401 | .set_offline = lcs_shutdown_device, | 2401 | .set_offline = lcs_shutdown_device, |
@@ -2406,30 +2406,24 @@ static struct ccwgroup_driver lcs_group_driver = { | |||
2406 | .restore = lcs_restore, | 2406 | .restore = lcs_restore, |
2407 | }; | 2407 | }; |
2408 | 2408 | ||
2409 | static ssize_t | 2409 | static ssize_t lcs_driver_group_store(struct device_driver *ddrv, |
2410 | lcs_driver_group_store(struct device_driver *ddrv, const char *buf, | 2410 | const char *buf, size_t count) |
2411 | size_t count) | ||
2412 | { | 2411 | { |
2413 | int err; | 2412 | int err; |
2414 | err = ccwgroup_create_from_string(lcs_root_dev, | 2413 | err = ccwgroup_create_dev(lcs_root_dev, &lcs_group_driver, 2, buf); |
2415 | lcs_group_driver.driver_id, | ||
2416 | &lcs_ccw_driver, 2, buf); | ||
2417 | return err ? err : count; | 2414 | return err ? err : count; |
2418 | } | 2415 | } |
2419 | |||
2420 | static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store); | 2416 | static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store); |
2421 | 2417 | ||
2422 | static struct attribute *lcs_group_attrs[] = { | 2418 | static struct attribute *lcs_drv_attrs[] = { |
2423 | &driver_attr_group.attr, | 2419 | &driver_attr_group.attr, |
2424 | NULL, | 2420 | NULL, |
2425 | }; | 2421 | }; |
2426 | 2422 | static struct attribute_group lcs_drv_attr_group = { | |
2427 | static struct attribute_group lcs_group_attr_group = { | 2423 | .attrs = lcs_drv_attrs, |
2428 | .attrs = lcs_group_attrs, | ||
2429 | }; | 2424 | }; |
2430 | 2425 | static const struct attribute_group *lcs_drv_attr_groups[] = { | |
2431 | static const struct attribute_group *lcs_group_attr_groups[] = { | 2426 | &lcs_drv_attr_group, |
2432 | &lcs_group_attr_group, | ||
2433 | NULL, | 2427 | NULL, |
2434 | }; | 2428 | }; |
2435 | 2429 | ||
@@ -2453,7 +2447,7 @@ __init lcs_init_module(void) | |||
2453 | rc = ccw_driver_register(&lcs_ccw_driver); | 2447 | rc = ccw_driver_register(&lcs_ccw_driver); |
2454 | if (rc) | 2448 | if (rc) |
2455 | goto ccw_err; | 2449 | goto ccw_err; |
2456 | lcs_group_driver.driver.groups = lcs_group_attr_groups; | 2450 | lcs_group_driver.driver.groups = lcs_drv_attr_groups; |
2457 | rc = ccwgroup_driver_register(&lcs_group_driver); | 2451 | rc = ccwgroup_driver_register(&lcs_group_driver); |
2458 | if (rc) | 2452 | if (rc) |
2459 | goto ccwgroup_err; | 2453 | goto ccwgroup_err; |
@@ -2479,8 +2473,6 @@ __exit lcs_cleanup_module(void) | |||
2479 | { | 2473 | { |
2480 | pr_info("Terminating lcs module.\n"); | 2474 | pr_info("Terminating lcs module.\n"); |
2481 | LCS_DBF_TEXT(0, trace, "cleanup"); | 2475 | LCS_DBF_TEXT(0, trace, "cleanup"); |
2482 | driver_remove_file(&lcs_group_driver.driver, | ||
2483 | &driver_attr_group); | ||
2484 | ccwgroup_driver_unregister(&lcs_group_driver); | 2476 | ccwgroup_driver_unregister(&lcs_group_driver); |
2485 | ccw_driver_unregister(&lcs_ccw_driver); | 2477 | ccw_driver_unregister(&lcs_ccw_driver); |
2486 | root_device_unregister(lcs_root_dev); | 2478 | root_device_unregister(lcs_root_dev); |
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 40285dc9ae5c..06e8f31ff3dc 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
@@ -707,7 +707,16 @@ struct qeth_discipline { | |||
707 | qdio_handler_t *input_handler; | 707 | qdio_handler_t *input_handler; |
708 | qdio_handler_t *output_handler; | 708 | qdio_handler_t *output_handler; |
709 | int (*recover)(void *ptr); | 709 | int (*recover)(void *ptr); |
710 | struct ccwgroup_driver *ccwgdriver; | 710 | int (*setup) (struct ccwgroup_device *); |
711 | void (*remove) (struct ccwgroup_device *); | ||
712 | int (*set_online) (struct ccwgroup_device *); | ||
713 | int (*set_offline) (struct ccwgroup_device *); | ||
714 | void (*shutdown)(struct ccwgroup_device *); | ||
715 | int (*prepare) (struct ccwgroup_device *); | ||
716 | void (*complete) (struct ccwgroup_device *); | ||
717 | int (*freeze)(struct ccwgroup_device *); | ||
718 | int (*thaw) (struct ccwgroup_device *); | ||
719 | int (*restore)(struct ccwgroup_device *); | ||
711 | }; | 720 | }; |
712 | 721 | ||
713 | struct qeth_vlan_vid { | 722 | struct qeth_vlan_vid { |
@@ -771,7 +780,7 @@ struct qeth_card { | |||
771 | struct qeth_perf_stats perf_stats; | 780 | struct qeth_perf_stats perf_stats; |
772 | int read_or_write_problem; | 781 | int read_or_write_problem; |
773 | struct qeth_osn_info osn_info; | 782 | struct qeth_osn_info osn_info; |
774 | struct qeth_discipline discipline; | 783 | struct qeth_discipline *discipline; |
775 | atomic_t force_alloc_skb; | 784 | atomic_t force_alloc_skb; |
776 | struct service_level qeth_service_level; | 785 | struct service_level qeth_service_level; |
777 | struct qdio_ssqd_desc ssqd; | 786 | struct qdio_ssqd_desc ssqd; |
@@ -837,16 +846,15 @@ static inline int qeth_is_diagass_supported(struct qeth_card *card, | |||
837 | return card->info.diagass_support & (__u32)cmd; | 846 | return card->info.diagass_support & (__u32)cmd; |
838 | } | 847 | } |
839 | 848 | ||
840 | extern struct ccwgroup_driver qeth_l2_ccwgroup_driver; | 849 | extern struct qeth_discipline qeth_l2_discipline; |
841 | extern struct ccwgroup_driver qeth_l3_ccwgroup_driver; | 850 | extern struct qeth_discipline qeth_l3_discipline; |
851 | extern const struct attribute_group *qeth_generic_attr_groups[]; | ||
852 | extern const struct attribute_group *qeth_osn_attr_groups[]; | ||
853 | |||
842 | const char *qeth_get_cardname_short(struct qeth_card *); | 854 | const char *qeth_get_cardname_short(struct qeth_card *); |
843 | int qeth_realloc_buffer_pool(struct qeth_card *, int); | 855 | int qeth_realloc_buffer_pool(struct qeth_card *, int); |
844 | int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id); | 856 | int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id); |
845 | void qeth_core_free_discipline(struct qeth_card *); | 857 | void qeth_core_free_discipline(struct qeth_card *); |
846 | int qeth_core_create_device_attributes(struct device *); | ||
847 | void qeth_core_remove_device_attributes(struct device *); | ||
848 | int qeth_core_create_osn_attributes(struct device *); | ||
849 | void qeth_core_remove_osn_attributes(struct device *); | ||
850 | void qeth_buffer_reclaim_work(struct work_struct *); | 858 | void qeth_buffer_reclaim_work(struct work_struct *); |
851 | 859 | ||
852 | /* exports for qeth discipline device drivers */ | 860 | /* exports for qeth discipline device drivers */ |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index e000001539bf..e118e1e1e1c1 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -1363,7 +1363,7 @@ static void qeth_start_kernel_thread(struct work_struct *work) | |||
1363 | card->write.state != CH_STATE_UP) | 1363 | card->write.state != CH_STATE_UP) |
1364 | return; | 1364 | return; |
1365 | if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) { | 1365 | if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) { |
1366 | ts = kthread_run(card->discipline.recover, (void *)card, | 1366 | ts = kthread_run(card->discipline->recover, (void *)card, |
1367 | "qeth_recover"); | 1367 | "qeth_recover"); |
1368 | if (IS_ERR(ts)) { | 1368 | if (IS_ERR(ts)) { |
1369 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); | 1369 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); |
@@ -3337,7 +3337,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, | |||
3337 | if (rc) { | 3337 | if (rc) { |
3338 | queue->card->stats.tx_errors += count; | 3338 | queue->card->stats.tx_errors += count; |
3339 | /* ignore temporary SIGA errors without busy condition */ | 3339 | /* ignore temporary SIGA errors without busy condition */ |
3340 | if (rc == QDIO_ERROR_SIGA_TARGET) | 3340 | if (rc == -ENOBUFS) |
3341 | return; | 3341 | return; |
3342 | QETH_CARD_TEXT(queue->card, 2, "flushbuf"); | 3342 | QETH_CARD_TEXT(queue->card, 2, "flushbuf"); |
3343 | QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no); | 3343 | QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no); |
@@ -3531,7 +3531,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, | |||
3531 | int i; | 3531 | int i; |
3532 | 3532 | ||
3533 | QETH_CARD_TEXT(card, 6, "qdouhdl"); | 3533 | QETH_CARD_TEXT(card, 6, "qdouhdl"); |
3534 | if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { | 3534 | if (qdio_error & QDIO_ERROR_FATAL) { |
3535 | QETH_CARD_TEXT(card, 2, "achkcond"); | 3535 | QETH_CARD_TEXT(card, 2, "achkcond"); |
3536 | netif_stop_queue(card->dev); | 3536 | netif_stop_queue(card->dev); |
3537 | qeth_schedule_recovery(card); | 3537 | qeth_schedule_recovery(card); |
@@ -4627,7 +4627,7 @@ static int qeth_qdio_establish(struct qeth_card *card) | |||
4627 | goto out_free_in_sbals; | 4627 | goto out_free_in_sbals; |
4628 | } | 4628 | } |
4629 | for (i = 0; i < card->qdio.no_in_queues; ++i) | 4629 | for (i = 0; i < card->qdio.no_in_queues; ++i) |
4630 | queue_start_poll[i] = card->discipline.start_poll; | 4630 | queue_start_poll[i] = card->discipline->start_poll; |
4631 | 4631 | ||
4632 | qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll); | 4632 | qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll); |
4633 | 4633 | ||
@@ -4651,8 +4651,8 @@ static int qeth_qdio_establish(struct qeth_card *card) | |||
4651 | init_data.qib_param_field = qib_param_field; | 4651 | init_data.qib_param_field = qib_param_field; |
4652 | init_data.no_input_qs = card->qdio.no_in_queues; | 4652 | init_data.no_input_qs = card->qdio.no_in_queues; |
4653 | init_data.no_output_qs = card->qdio.no_out_queues; | 4653 | init_data.no_output_qs = card->qdio.no_out_queues; |
4654 | init_data.input_handler = card->discipline.input_handler; | 4654 | init_data.input_handler = card->discipline->input_handler; |
4655 | init_data.output_handler = card->discipline.output_handler; | 4655 | init_data.output_handler = card->discipline->output_handler; |
4656 | init_data.queue_start_poll_array = queue_start_poll; | 4656 | init_data.queue_start_poll_array = queue_start_poll; |
4657 | init_data.int_parm = (unsigned long) card; | 4657 | init_data.int_parm = (unsigned long) card; |
4658 | init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; | 4658 | init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; |
@@ -4737,13 +4737,6 @@ static struct ccw_driver qeth_ccw_driver = { | |||
4737 | .remove = ccwgroup_remove_ccwdev, | 4737 | .remove = ccwgroup_remove_ccwdev, |
4738 | }; | 4738 | }; |
4739 | 4739 | ||
4740 | static int qeth_core_driver_group(const char *buf, struct device *root_dev, | ||
4741 | unsigned long driver_id) | ||
4742 | { | ||
4743 | return ccwgroup_create_from_string(root_dev, driver_id, | ||
4744 | &qeth_ccw_driver, 3, buf); | ||
4745 | } | ||
4746 | |||
4747 | int qeth_core_hardsetup_card(struct qeth_card *card) | 4740 | int qeth_core_hardsetup_card(struct qeth_card *card) |
4748 | { | 4741 | { |
4749 | int retries = 0; | 4742 | int retries = 0; |
@@ -5040,17 +5033,15 @@ int qeth_core_load_discipline(struct qeth_card *card, | |||
5040 | mutex_lock(&qeth_mod_mutex); | 5033 | mutex_lock(&qeth_mod_mutex); |
5041 | switch (discipline) { | 5034 | switch (discipline) { |
5042 | case QETH_DISCIPLINE_LAYER3: | 5035 | case QETH_DISCIPLINE_LAYER3: |
5043 | card->discipline.ccwgdriver = try_then_request_module( | 5036 | card->discipline = try_then_request_module( |
5044 | symbol_get(qeth_l3_ccwgroup_driver), | 5037 | symbol_get(qeth_l3_discipline), "qeth_l3"); |
5045 | "qeth_l3"); | ||
5046 | break; | 5038 | break; |
5047 | case QETH_DISCIPLINE_LAYER2: | 5039 | case QETH_DISCIPLINE_LAYER2: |
5048 | card->discipline.ccwgdriver = try_then_request_module( | 5040 | card->discipline = try_then_request_module( |
5049 | symbol_get(qeth_l2_ccwgroup_driver), | 5041 | symbol_get(qeth_l2_discipline), "qeth_l2"); |
5050 | "qeth_l2"); | ||
5051 | break; | 5042 | break; |
5052 | } | 5043 | } |
5053 | if (!card->discipline.ccwgdriver) { | 5044 | if (!card->discipline) { |
5054 | dev_err(&card->gdev->dev, "There is no kernel module to " | 5045 | dev_err(&card->gdev->dev, "There is no kernel module to " |
5055 | "support discipline %d\n", discipline); | 5046 | "support discipline %d\n", discipline); |
5056 | rc = -EINVAL; | 5047 | rc = -EINVAL; |
@@ -5062,12 +5053,21 @@ int qeth_core_load_discipline(struct qeth_card *card, | |||
5062 | void qeth_core_free_discipline(struct qeth_card *card) | 5053 | void qeth_core_free_discipline(struct qeth_card *card) |
5063 | { | 5054 | { |
5064 | if (card->options.layer2) | 5055 | if (card->options.layer2) |
5065 | symbol_put(qeth_l2_ccwgroup_driver); | 5056 | symbol_put(qeth_l2_discipline); |
5066 | else | 5057 | else |
5067 | symbol_put(qeth_l3_ccwgroup_driver); | 5058 | symbol_put(qeth_l3_discipline); |
5068 | card->discipline.ccwgdriver = NULL; | 5059 | card->discipline = NULL; |
5069 | } | 5060 | } |
5070 | 5061 | ||
5062 | static const struct device_type qeth_generic_devtype = { | ||
5063 | .name = "qeth_generic", | ||
5064 | .groups = qeth_generic_attr_groups, | ||
5065 | }; | ||
5066 | static const struct device_type qeth_osn_devtype = { | ||
5067 | .name = "qeth_osn", | ||
5068 | .groups = qeth_osn_attr_groups, | ||
5069 | }; | ||
5070 | |||
5071 | static int qeth_core_probe_device(struct ccwgroup_device *gdev) | 5071 | static int qeth_core_probe_device(struct ccwgroup_device *gdev) |
5072 | { | 5072 | { |
5073 | struct qeth_card *card; | 5073 | struct qeth_card *card; |
@@ -5122,18 +5122,17 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) | |||
5122 | } | 5122 | } |
5123 | 5123 | ||
5124 | if (card->info.type == QETH_CARD_TYPE_OSN) | 5124 | if (card->info.type == QETH_CARD_TYPE_OSN) |
5125 | rc = qeth_core_create_osn_attributes(dev); | 5125 | gdev->dev.type = &qeth_osn_devtype; |
5126 | else | 5126 | else |
5127 | rc = qeth_core_create_device_attributes(dev); | 5127 | gdev->dev.type = &qeth_generic_devtype; |
5128 | if (rc) | 5128 | |
5129 | goto err_dbf; | ||
5130 | switch (card->info.type) { | 5129 | switch (card->info.type) { |
5131 | case QETH_CARD_TYPE_OSN: | 5130 | case QETH_CARD_TYPE_OSN: |
5132 | case QETH_CARD_TYPE_OSM: | 5131 | case QETH_CARD_TYPE_OSM: |
5133 | rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); | 5132 | rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); |
5134 | if (rc) | 5133 | if (rc) |
5135 | goto err_attr; | 5134 | goto err_dbf; |
5136 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 5135 | rc = card->discipline->setup(card->gdev); |
5137 | if (rc) | 5136 | if (rc) |
5138 | goto err_disc; | 5137 | goto err_disc; |
5139 | case QETH_CARD_TYPE_OSD: | 5138 | case QETH_CARD_TYPE_OSD: |
@@ -5151,11 +5150,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) | |||
5151 | 5150 | ||
5152 | err_disc: | 5151 | err_disc: |
5153 | qeth_core_free_discipline(card); | 5152 | qeth_core_free_discipline(card); |
5154 | err_attr: | ||
5155 | if (card->info.type == QETH_CARD_TYPE_OSN) | ||
5156 | qeth_core_remove_osn_attributes(dev); | ||
5157 | else | ||
5158 | qeth_core_remove_device_attributes(dev); | ||
5159 | err_dbf: | 5153 | err_dbf: |
5160 | debug_unregister(card->debug); | 5154 | debug_unregister(card->debug); |
5161 | err_card: | 5155 | err_card: |
@@ -5172,14 +5166,8 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) | |||
5172 | 5166 | ||
5173 | QETH_DBF_TEXT(SETUP, 2, "removedv"); | 5167 | QETH_DBF_TEXT(SETUP, 2, "removedv"); |
5174 | 5168 | ||
5175 | if (card->info.type == QETH_CARD_TYPE_OSN) { | 5169 | if (card->discipline) { |
5176 | qeth_core_remove_osn_attributes(&gdev->dev); | 5170 | card->discipline->remove(gdev); |
5177 | } else { | ||
5178 | qeth_core_remove_device_attributes(&gdev->dev); | ||
5179 | } | ||
5180 | |||
5181 | if (card->discipline.ccwgdriver) { | ||
5182 | card->discipline.ccwgdriver->remove(gdev); | ||
5183 | qeth_core_free_discipline(card); | 5171 | qeth_core_free_discipline(card); |
5184 | } | 5172 | } |
5185 | 5173 | ||
@@ -5199,7 +5187,7 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) | |||
5199 | int rc = 0; | 5187 | int rc = 0; |
5200 | int def_discipline; | 5188 | int def_discipline; |
5201 | 5189 | ||
5202 | if (!card->discipline.ccwgdriver) { | 5190 | if (!card->discipline) { |
5203 | if (card->info.type == QETH_CARD_TYPE_IQD) | 5191 | if (card->info.type == QETH_CARD_TYPE_IQD) |
5204 | def_discipline = QETH_DISCIPLINE_LAYER3; | 5192 | def_discipline = QETH_DISCIPLINE_LAYER3; |
5205 | else | 5193 | else |
@@ -5207,11 +5195,11 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) | |||
5207 | rc = qeth_core_load_discipline(card, def_discipline); | 5195 | rc = qeth_core_load_discipline(card, def_discipline); |
5208 | if (rc) | 5196 | if (rc) |
5209 | goto err; | 5197 | goto err; |
5210 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 5198 | rc = card->discipline->setup(card->gdev); |
5211 | if (rc) | 5199 | if (rc) |
5212 | goto err; | 5200 | goto err; |
5213 | } | 5201 | } |
5214 | rc = card->discipline.ccwgdriver->set_online(gdev); | 5202 | rc = card->discipline->set_online(gdev); |
5215 | err: | 5203 | err: |
5216 | return rc; | 5204 | return rc; |
5217 | } | 5205 | } |
@@ -5219,58 +5207,52 @@ err: | |||
5219 | static int qeth_core_set_offline(struct ccwgroup_device *gdev) | 5207 | static int qeth_core_set_offline(struct ccwgroup_device *gdev) |
5220 | { | 5208 | { |
5221 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5209 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5222 | return card->discipline.ccwgdriver->set_offline(gdev); | 5210 | return card->discipline->set_offline(gdev); |
5223 | } | 5211 | } |
5224 | 5212 | ||
5225 | static void qeth_core_shutdown(struct ccwgroup_device *gdev) | 5213 | static void qeth_core_shutdown(struct ccwgroup_device *gdev) |
5226 | { | 5214 | { |
5227 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5215 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5228 | if (card->discipline.ccwgdriver && | 5216 | if (card->discipline && card->discipline->shutdown) |
5229 | card->discipline.ccwgdriver->shutdown) | 5217 | card->discipline->shutdown(gdev); |
5230 | card->discipline.ccwgdriver->shutdown(gdev); | ||
5231 | } | 5218 | } |
5232 | 5219 | ||
5233 | static int qeth_core_prepare(struct ccwgroup_device *gdev) | 5220 | static int qeth_core_prepare(struct ccwgroup_device *gdev) |
5234 | { | 5221 | { |
5235 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5222 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5236 | if (card->discipline.ccwgdriver && | 5223 | if (card->discipline && card->discipline->prepare) |
5237 | card->discipline.ccwgdriver->prepare) | 5224 | return card->discipline->prepare(gdev); |
5238 | return card->discipline.ccwgdriver->prepare(gdev); | ||
5239 | return 0; | 5225 | return 0; |
5240 | } | 5226 | } |
5241 | 5227 | ||
5242 | static void qeth_core_complete(struct ccwgroup_device *gdev) | 5228 | static void qeth_core_complete(struct ccwgroup_device *gdev) |
5243 | { | 5229 | { |
5244 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5230 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5245 | if (card->discipline.ccwgdriver && | 5231 | if (card->discipline && card->discipline->complete) |
5246 | card->discipline.ccwgdriver->complete) | 5232 | card->discipline->complete(gdev); |
5247 | card->discipline.ccwgdriver->complete(gdev); | ||
5248 | } | 5233 | } |
5249 | 5234 | ||
5250 | static int qeth_core_freeze(struct ccwgroup_device *gdev) | 5235 | static int qeth_core_freeze(struct ccwgroup_device *gdev) |
5251 | { | 5236 | { |
5252 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5237 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5253 | if (card->discipline.ccwgdriver && | 5238 | if (card->discipline && card->discipline->freeze) |
5254 | card->discipline.ccwgdriver->freeze) | 5239 | return card->discipline->freeze(gdev); |
5255 | return card->discipline.ccwgdriver->freeze(gdev); | ||
5256 | return 0; | 5240 | return 0; |
5257 | } | 5241 | } |
5258 | 5242 | ||
5259 | static int qeth_core_thaw(struct ccwgroup_device *gdev) | 5243 | static int qeth_core_thaw(struct ccwgroup_device *gdev) |
5260 | { | 5244 | { |
5261 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5245 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5262 | if (card->discipline.ccwgdriver && | 5246 | if (card->discipline && card->discipline->thaw) |
5263 | card->discipline.ccwgdriver->thaw) | 5247 | return card->discipline->thaw(gdev); |
5264 | return card->discipline.ccwgdriver->thaw(gdev); | ||
5265 | return 0; | 5248 | return 0; |
5266 | } | 5249 | } |
5267 | 5250 | ||
5268 | static int qeth_core_restore(struct ccwgroup_device *gdev) | 5251 | static int qeth_core_restore(struct ccwgroup_device *gdev) |
5269 | { | 5252 | { |
5270 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5253 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5271 | if (card->discipline.ccwgdriver && | 5254 | if (card->discipline && card->discipline->restore) |
5272 | card->discipline.ccwgdriver->restore) | 5255 | return card->discipline->restore(gdev); |
5273 | return card->discipline.ccwgdriver->restore(gdev); | ||
5274 | return 0; | 5256 | return 0; |
5275 | } | 5257 | } |
5276 | 5258 | ||
@@ -5279,8 +5261,7 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = { | |||
5279 | .owner = THIS_MODULE, | 5261 | .owner = THIS_MODULE, |
5280 | .name = "qeth", | 5262 | .name = "qeth", |
5281 | }, | 5263 | }, |
5282 | .driver_id = 0xD8C5E3C8, | 5264 | .setup = qeth_core_probe_device, |
5283 | .probe = qeth_core_probe_device, | ||
5284 | .remove = qeth_core_remove_device, | 5265 | .remove = qeth_core_remove_device, |
5285 | .set_online = qeth_core_set_online, | 5266 | .set_online = qeth_core_set_online, |
5286 | .set_offline = qeth_core_set_offline, | 5267 | .set_offline = qeth_core_set_offline, |
@@ -5292,21 +5273,30 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = { | |||
5292 | .restore = qeth_core_restore, | 5273 | .restore = qeth_core_restore, |
5293 | }; | 5274 | }; |
5294 | 5275 | ||
5295 | static ssize_t | 5276 | static ssize_t qeth_core_driver_group_store(struct device_driver *ddrv, |
5296 | qeth_core_driver_group_store(struct device_driver *ddrv, const char *buf, | 5277 | const char *buf, size_t count) |
5297 | size_t count) | ||
5298 | { | 5278 | { |
5299 | int err; | 5279 | int err; |
5300 | err = qeth_core_driver_group(buf, qeth_core_root_dev, | ||
5301 | qeth_core_ccwgroup_driver.driver_id); | ||
5302 | if (err) | ||
5303 | return err; | ||
5304 | else | ||
5305 | return count; | ||
5306 | } | ||
5307 | 5280 | ||
5281 | err = ccwgroup_create_dev(qeth_core_root_dev, | ||
5282 | &qeth_core_ccwgroup_driver, 3, buf); | ||
5283 | |||
5284 | return err ? err : count; | ||
5285 | } | ||
5308 | static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store); | 5286 | static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store); |
5309 | 5287 | ||
5288 | static struct attribute *qeth_drv_attrs[] = { | ||
5289 | &driver_attr_group.attr, | ||
5290 | NULL, | ||
5291 | }; | ||
5292 | static struct attribute_group qeth_drv_attr_group = { | ||
5293 | .attrs = qeth_drv_attrs, | ||
5294 | }; | ||
5295 | static const struct attribute_group *qeth_drv_attr_groups[] = { | ||
5296 | &qeth_drv_attr_group, | ||
5297 | NULL, | ||
5298 | }; | ||
5299 | |||
5310 | static struct { | 5300 | static struct { |
5311 | const char str[ETH_GSTRING_LEN]; | 5301 | const char str[ETH_GSTRING_LEN]; |
5312 | } qeth_ethtool_stats_keys[] = { | 5302 | } qeth_ethtool_stats_keys[] = { |
@@ -5544,49 +5534,41 @@ static int __init qeth_core_init(void) | |||
5544 | rc = qeth_register_dbf_views(); | 5534 | rc = qeth_register_dbf_views(); |
5545 | if (rc) | 5535 | if (rc) |
5546 | goto out_err; | 5536 | goto out_err; |
5547 | rc = ccw_driver_register(&qeth_ccw_driver); | ||
5548 | if (rc) | ||
5549 | goto ccw_err; | ||
5550 | rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver); | ||
5551 | if (rc) | ||
5552 | goto ccwgroup_err; | ||
5553 | rc = driver_create_file(&qeth_core_ccwgroup_driver.driver, | ||
5554 | &driver_attr_group); | ||
5555 | if (rc) | ||
5556 | goto driver_err; | ||
5557 | qeth_core_root_dev = root_device_register("qeth"); | 5537 | qeth_core_root_dev = root_device_register("qeth"); |
5558 | rc = IS_ERR(qeth_core_root_dev) ? PTR_ERR(qeth_core_root_dev) : 0; | 5538 | rc = IS_ERR(qeth_core_root_dev) ? PTR_ERR(qeth_core_root_dev) : 0; |
5559 | if (rc) | 5539 | if (rc) |
5560 | goto register_err; | 5540 | goto register_err; |
5561 | |||
5562 | qeth_core_header_cache = kmem_cache_create("qeth_hdr", | 5541 | qeth_core_header_cache = kmem_cache_create("qeth_hdr", |
5563 | sizeof(struct qeth_hdr) + ETH_HLEN, 64, 0, NULL); | 5542 | sizeof(struct qeth_hdr) + ETH_HLEN, 64, 0, NULL); |
5564 | if (!qeth_core_header_cache) { | 5543 | if (!qeth_core_header_cache) { |
5565 | rc = -ENOMEM; | 5544 | rc = -ENOMEM; |
5566 | goto slab_err; | 5545 | goto slab_err; |
5567 | } | 5546 | } |
5568 | |||
5569 | qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf", | 5547 | qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf", |
5570 | sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL); | 5548 | sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL); |
5571 | if (!qeth_qdio_outbuf_cache) { | 5549 | if (!qeth_qdio_outbuf_cache) { |
5572 | rc = -ENOMEM; | 5550 | rc = -ENOMEM; |
5573 | goto cqslab_err; | 5551 | goto cqslab_err; |
5574 | } | 5552 | } |
5553 | rc = ccw_driver_register(&qeth_ccw_driver); | ||
5554 | if (rc) | ||
5555 | goto ccw_err; | ||
5556 | qeth_core_ccwgroup_driver.driver.groups = qeth_drv_attr_groups; | ||
5557 | rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver); | ||
5558 | if (rc) | ||
5559 | goto ccwgroup_err; | ||
5575 | 5560 | ||
5576 | return 0; | 5561 | return 0; |
5562 | |||
5563 | ccwgroup_err: | ||
5564 | ccw_driver_unregister(&qeth_ccw_driver); | ||
5565 | ccw_err: | ||
5566 | kmem_cache_destroy(qeth_qdio_outbuf_cache); | ||
5577 | cqslab_err: | 5567 | cqslab_err: |
5578 | kmem_cache_destroy(qeth_core_header_cache); | 5568 | kmem_cache_destroy(qeth_core_header_cache); |
5579 | slab_err: | 5569 | slab_err: |
5580 | root_device_unregister(qeth_core_root_dev); | 5570 | root_device_unregister(qeth_core_root_dev); |
5581 | register_err: | 5571 | register_err: |
5582 | driver_remove_file(&qeth_core_ccwgroup_driver.driver, | ||
5583 | &driver_attr_group); | ||
5584 | driver_err: | ||
5585 | ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); | ||
5586 | ccwgroup_err: | ||
5587 | ccw_driver_unregister(&qeth_ccw_driver); | ||
5588 | ccw_err: | ||
5589 | QETH_DBF_MESSAGE(2, "Initialization failed with code %d\n", rc); | ||
5590 | qeth_unregister_dbf_views(); | 5572 | qeth_unregister_dbf_views(); |
5591 | out_err: | 5573 | out_err: |
5592 | pr_err("Initializing the qeth device driver failed\n"); | 5574 | pr_err("Initializing the qeth device driver failed\n"); |
@@ -5595,13 +5577,11 @@ out_err: | |||
5595 | 5577 | ||
5596 | static void __exit qeth_core_exit(void) | 5578 | static void __exit qeth_core_exit(void) |
5597 | { | 5579 | { |
5598 | root_device_unregister(qeth_core_root_dev); | ||
5599 | driver_remove_file(&qeth_core_ccwgroup_driver.driver, | ||
5600 | &driver_attr_group); | ||
5601 | ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); | 5580 | ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); |
5602 | ccw_driver_unregister(&qeth_ccw_driver); | 5581 | ccw_driver_unregister(&qeth_ccw_driver); |
5603 | kmem_cache_destroy(qeth_qdio_outbuf_cache); | 5582 | kmem_cache_destroy(qeth_qdio_outbuf_cache); |
5604 | kmem_cache_destroy(qeth_core_header_cache); | 5583 | kmem_cache_destroy(qeth_core_header_cache); |
5584 | root_device_unregister(qeth_core_root_dev); | ||
5605 | qeth_unregister_dbf_views(); | 5585 | qeth_unregister_dbf_views(); |
5606 | pr_info("core functions removed\n"); | 5586 | pr_info("core functions removed\n"); |
5607 | } | 5587 | } |
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 0a8e86c1b0ea..f163af575c48 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c | |||
@@ -434,8 +434,8 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
434 | goto out; | 434 | goto out; |
435 | else { | 435 | else { |
436 | card->info.mac_bits = 0; | 436 | card->info.mac_bits = 0; |
437 | if (card->discipline.ccwgdriver) { | 437 | if (card->discipline) { |
438 | card->discipline.ccwgdriver->remove(card->gdev); | 438 | card->discipline->remove(card->gdev); |
439 | qeth_core_free_discipline(card); | 439 | qeth_core_free_discipline(card); |
440 | } | 440 | } |
441 | } | 441 | } |
@@ -444,7 +444,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
444 | if (rc) | 444 | if (rc) |
445 | goto out; | 445 | goto out; |
446 | 446 | ||
447 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 447 | rc = card->discipline->setup(card->gdev); |
448 | out: | 448 | out: |
449 | mutex_unlock(&card->discipline_mutex); | 449 | mutex_unlock(&card->discipline_mutex); |
450 | return rc ? rc : count; | 450 | return rc ? rc : count; |
@@ -693,7 +693,6 @@ static struct attribute *qeth_blkt_device_attrs[] = { | |||
693 | &dev_attr_inter_jumbo.attr, | 693 | &dev_attr_inter_jumbo.attr, |
694 | NULL, | 694 | NULL, |
695 | }; | 695 | }; |
696 | |||
697 | static struct attribute_group qeth_device_blkt_group = { | 696 | static struct attribute_group qeth_device_blkt_group = { |
698 | .name = "blkt", | 697 | .name = "blkt", |
699 | .attrs = qeth_blkt_device_attrs, | 698 | .attrs = qeth_blkt_device_attrs, |
@@ -716,11 +715,16 @@ static struct attribute *qeth_device_attrs[] = { | |||
716 | &dev_attr_hw_trap.attr, | 715 | &dev_attr_hw_trap.attr, |
717 | NULL, | 716 | NULL, |
718 | }; | 717 | }; |
719 | |||
720 | static struct attribute_group qeth_device_attr_group = { | 718 | static struct attribute_group qeth_device_attr_group = { |
721 | .attrs = qeth_device_attrs, | 719 | .attrs = qeth_device_attrs, |
722 | }; | 720 | }; |
723 | 721 | ||
722 | const struct attribute_group *qeth_generic_attr_groups[] = { | ||
723 | &qeth_device_attr_group, | ||
724 | &qeth_device_blkt_group, | ||
725 | NULL, | ||
726 | }; | ||
727 | |||
724 | static struct attribute *qeth_osn_device_attrs[] = { | 728 | static struct attribute *qeth_osn_device_attrs[] = { |
725 | &dev_attr_state.attr, | 729 | &dev_attr_state.attr, |
726 | &dev_attr_chpid.attr, | 730 | &dev_attr_chpid.attr, |
@@ -730,37 +734,10 @@ static struct attribute *qeth_osn_device_attrs[] = { | |||
730 | &dev_attr_recover.attr, | 734 | &dev_attr_recover.attr, |
731 | NULL, | 735 | NULL, |
732 | }; | 736 | }; |
733 | |||
734 | static struct attribute_group qeth_osn_device_attr_group = { | 737 | static struct attribute_group qeth_osn_device_attr_group = { |
735 | .attrs = qeth_osn_device_attrs, | 738 | .attrs = qeth_osn_device_attrs, |
736 | }; | 739 | }; |
737 | 740 | const struct attribute_group *qeth_osn_attr_groups[] = { | |
738 | int qeth_core_create_device_attributes(struct device *dev) | 741 | &qeth_osn_device_attr_group, |
739 | { | 742 | NULL, |
740 | int ret; | 743 | }; |
741 | ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group); | ||
742 | if (ret) | ||
743 | return ret; | ||
744 | ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group); | ||
745 | if (ret) | ||
746 | sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | void qeth_core_remove_device_attributes(struct device *dev) | ||
752 | { | ||
753 | sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); | ||
754 | sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group); | ||
755 | } | ||
756 | |||
757 | int qeth_core_create_osn_attributes(struct device *dev) | ||
758 | { | ||
759 | return sysfs_create_group(&dev->kobj, &qeth_osn_device_attr_group); | ||
760 | } | ||
761 | |||
762 | void qeth_core_remove_osn_attributes(struct device *dev) | ||
763 | { | ||
764 | sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group); | ||
765 | return; | ||
766 | } | ||
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 0e7c29d1d7ef..426986518e96 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -882,12 +882,6 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev) | |||
882 | INIT_LIST_HEAD(&card->mc_list); | 882 | INIT_LIST_HEAD(&card->mc_list); |
883 | card->options.layer2 = 1; | 883 | card->options.layer2 = 1; |
884 | card->info.hwtrap = 0; | 884 | card->info.hwtrap = 0; |
885 | card->discipline.start_poll = qeth_qdio_start_poll; | ||
886 | card->discipline.input_handler = (qdio_handler_t *) | ||
887 | qeth_qdio_input_handler; | ||
888 | card->discipline.output_handler = (qdio_handler_t *) | ||
889 | qeth_qdio_output_handler; | ||
890 | card->discipline.recover = qeth_l2_recover; | ||
891 | return 0; | 885 | return 0; |
892 | } | 886 | } |
893 | 887 | ||
@@ -1227,8 +1221,12 @@ out: | |||
1227 | return rc; | 1221 | return rc; |
1228 | } | 1222 | } |
1229 | 1223 | ||
1230 | struct ccwgroup_driver qeth_l2_ccwgroup_driver = { | 1224 | struct qeth_discipline qeth_l2_discipline = { |
1231 | .probe = qeth_l2_probe_device, | 1225 | .start_poll = qeth_qdio_start_poll, |
1226 | .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, | ||
1227 | .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, | ||
1228 | .recover = qeth_l2_recover, | ||
1229 | .setup = qeth_l2_probe_device, | ||
1232 | .remove = qeth_l2_remove_device, | 1230 | .remove = qeth_l2_remove_device, |
1233 | .set_online = qeth_l2_set_online, | 1231 | .set_online = qeth_l2_set_online, |
1234 | .set_offline = qeth_l2_set_offline, | 1232 | .set_offline = qeth_l2_set_offline, |
@@ -1237,7 +1235,7 @@ struct ccwgroup_driver qeth_l2_ccwgroup_driver = { | |||
1237 | .thaw = qeth_l2_pm_resume, | 1235 | .thaw = qeth_l2_pm_resume, |
1238 | .restore = qeth_l2_pm_resume, | 1236 | .restore = qeth_l2_pm_resume, |
1239 | }; | 1237 | }; |
1240 | EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver); | 1238 | EXPORT_SYMBOL_GPL(qeth_l2_discipline); |
1241 | 1239 | ||
1242 | static int qeth_osn_send_control_data(struct qeth_card *card, int len, | 1240 | static int qeth_osn_send_control_data(struct qeth_card *card, int len, |
1243 | struct qeth_cmd_buffer *iob) | 1241 | struct qeth_cmd_buffer *iob) |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e7ad03209cb2..7be5e9775691 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -3298,12 +3298,6 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev) | |||
3298 | qeth_l3_create_device_attributes(&gdev->dev); | 3298 | qeth_l3_create_device_attributes(&gdev->dev); |
3299 | card->options.layer2 = 0; | 3299 | card->options.layer2 = 0; |
3300 | card->info.hwtrap = 0; | 3300 | card->info.hwtrap = 0; |
3301 | card->discipline.start_poll = qeth_qdio_start_poll; | ||
3302 | card->discipline.input_handler = (qdio_handler_t *) | ||
3303 | qeth_qdio_input_handler; | ||
3304 | card->discipline.output_handler = (qdio_handler_t *) | ||
3305 | qeth_qdio_output_handler; | ||
3306 | card->discipline.recover = qeth_l3_recover; | ||
3307 | return 0; | 3301 | return 0; |
3308 | } | 3302 | } |
3309 | 3303 | ||
@@ -3578,8 +3572,12 @@ out: | |||
3578 | return rc; | 3572 | return rc; |
3579 | } | 3573 | } |
3580 | 3574 | ||
3581 | struct ccwgroup_driver qeth_l3_ccwgroup_driver = { | 3575 | struct qeth_discipline qeth_l3_discipline = { |
3582 | .probe = qeth_l3_probe_device, | 3576 | .start_poll = qeth_qdio_start_poll, |
3577 | .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, | ||
3578 | .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, | ||
3579 | .recover = qeth_l3_recover, | ||
3580 | .setup = qeth_l3_probe_device, | ||
3583 | .remove = qeth_l3_remove_device, | 3581 | .remove = qeth_l3_remove_device, |
3584 | .set_online = qeth_l3_set_online, | 3582 | .set_online = qeth_l3_set_online, |
3585 | .set_offline = qeth_l3_set_offline, | 3583 | .set_offline = qeth_l3_set_offline, |
@@ -3588,7 +3586,7 @@ struct ccwgroup_driver qeth_l3_ccwgroup_driver = { | |||
3588 | .thaw = qeth_l3_pm_resume, | 3586 | .thaw = qeth_l3_pm_resume, |
3589 | .restore = qeth_l3_pm_resume, | 3587 | .restore = qeth_l3_pm_resume, |
3590 | }; | 3588 | }; |
3591 | EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver); | 3589 | EXPORT_SYMBOL_GPL(qeth_l3_discipline); |
3592 | 3590 | ||
3593 | static int qeth_l3_ip_event(struct notifier_block *this, | 3591 | static int qeth_l3_ip_event(struct notifier_block *this, |
3594 | unsigned long event, void *ptr) | 3592 | unsigned long event, void *ptr) |