diff options
Diffstat (limited to 'drivers/s390')
30 files changed, 392 insertions, 1081 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/Kconfig b/drivers/s390/net/Kconfig index 9b66d2d1809b..dfda748c4000 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig | |||
@@ -4,11 +4,10 @@ menu "S/390 network device drivers" | |||
4 | config LCS | 4 | config LCS |
5 | def_tristate m | 5 | def_tristate m |
6 | prompt "Lan Channel Station Interface" | 6 | prompt "Lan Channel Station Interface" |
7 | depends on CCW && NETDEVICES && (ETHERNET || TR || FDDI) | 7 | depends on CCW && NETDEVICES && (ETHERNET || FDDI) |
8 | help | 8 | help |
9 | Select this option if you want to use LCS networking on IBM System z. | 9 | Select this option if you want to use LCS networking on IBM System z. |
10 | This device driver supports Token Ring (IEEE 802.5), | 10 | This device driver supports FDDI (IEEE 802.7) and Ethernet. |
11 | FDDI (IEEE 802.7) and Ethernet. | ||
12 | To compile as a module, choose M. The module name is lcs. | 11 | To compile as a module, choose M. The module name is lcs. |
13 | If you do not know what it is, it's safe to choose Y. | 12 | If you do not know what it is, it's safe to choose Y. |
14 | 13 | ||
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 687efe4d589a..a3adf4b1c60d 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/if.h> | 30 | #include <linux/if.h> |
31 | #include <linux/netdevice.h> | 31 | #include <linux/netdevice.h> |
32 | #include <linux/etherdevice.h> | 32 | #include <linux/etherdevice.h> |
33 | #include <linux/trdevice.h> | ||
34 | #include <linux/fddidevice.h> | 33 | #include <linux/fddidevice.h> |
35 | #include <linux/inetdevice.h> | 34 | #include <linux/inetdevice.h> |
36 | #include <linux/in.h> | 35 | #include <linux/in.h> |
@@ -50,8 +49,7 @@ | |||
50 | #include "lcs.h" | 49 | #include "lcs.h" |
51 | 50 | ||
52 | 51 | ||
53 | #if !defined(CONFIG_ETHERNET) && \ | 52 | #if !defined(CONFIG_ETHERNET) && !defined(CONFIG_FDDI) |
54 | !defined(CONFIG_TR) && !defined(CONFIG_FDDI) | ||
55 | #error Cannot compile lcs.c without some net devices switched on. | 53 | #error Cannot compile lcs.c without some net devices switched on. |
56 | #endif | 54 | #endif |
57 | 55 | ||
@@ -1166,10 +1164,7 @@ static void | |||
1166 | lcs_get_mac_for_ipm(__be32 ipm, char *mac, struct net_device *dev) | 1164 | lcs_get_mac_for_ipm(__be32 ipm, char *mac, struct net_device *dev) |
1167 | { | 1165 | { |
1168 | LCS_DBF_TEXT(4,trace, "getmac"); | 1166 | LCS_DBF_TEXT(4,trace, "getmac"); |
1169 | if (dev->type == ARPHRD_IEEE802_TR) | 1167 | ip_eth_mc_map(ipm, mac); |
1170 | ip_tr_mc_map(ipm, mac); | ||
1171 | else | ||
1172 | ip_eth_mc_map(ipm, mac); | ||
1173 | } | 1168 | } |
1174 | 1169 | ||
1175 | /** | 1170 | /** |
@@ -1641,12 +1636,6 @@ lcs_startlan_auto(struct lcs_card *card) | |||
1641 | return 0; | 1636 | return 0; |
1642 | 1637 | ||
1643 | #endif | 1638 | #endif |
1644 | #ifdef CONFIG_TR | ||
1645 | card->lan_type = LCS_FRAME_TYPE_TR; | ||
1646 | rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP); | ||
1647 | if (rc == 0) | ||
1648 | return 0; | ||
1649 | #endif | ||
1650 | #ifdef CONFIG_FDDI | 1639 | #ifdef CONFIG_FDDI |
1651 | card->lan_type = LCS_FRAME_TYPE_FDDI; | 1640 | card->lan_type = LCS_FRAME_TYPE_FDDI; |
1652 | rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP); | 1641 | rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP); |
@@ -2051,10 +2040,17 @@ static struct attribute * lcs_attrs[] = { | |||
2051 | &dev_attr_recover.attr, | 2040 | &dev_attr_recover.attr, |
2052 | NULL, | 2041 | NULL, |
2053 | }; | 2042 | }; |
2054 | |||
2055 | static struct attribute_group lcs_attr_group = { | 2043 | static struct attribute_group lcs_attr_group = { |
2056 | .attrs = lcs_attrs, | 2044 | .attrs = lcs_attrs, |
2057 | }; | 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 | }; | ||
2058 | 2054 | ||
2059 | /** | 2055 | /** |
2060 | * lcs_probe_device is called on establishing a new ccwgroup_device. | 2056 | * lcs_probe_device is called on establishing a new ccwgroup_device. |
@@ -2063,7 +2059,6 @@ static int | |||
2063 | lcs_probe_device(struct ccwgroup_device *ccwgdev) | 2059 | lcs_probe_device(struct ccwgroup_device *ccwgdev) |
2064 | { | 2060 | { |
2065 | struct lcs_card *card; | 2061 | struct lcs_card *card; |
2066 | int ret; | ||
2067 | 2062 | ||
2068 | if (!get_device(&ccwgdev->dev)) | 2063 | if (!get_device(&ccwgdev->dev)) |
2069 | return -ENODEV; | 2064 | return -ENODEV; |
@@ -2075,12 +2070,6 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) | |||
2075 | put_device(&ccwgdev->dev); | 2070 | put_device(&ccwgdev->dev); |
2076 | return -ENOMEM; | 2071 | return -ENOMEM; |
2077 | } | 2072 | } |
2078 | ret = sysfs_create_group(&ccwgdev->dev.kobj, &lcs_attr_group); | ||
2079 | if (ret) { | ||
2080 | lcs_free_card(card); | ||
2081 | put_device(&ccwgdev->dev); | ||
2082 | return ret; | ||
2083 | } | ||
2084 | dev_set_drvdata(&ccwgdev->dev, card); | 2073 | dev_set_drvdata(&ccwgdev->dev, card); |
2085 | ccwgdev->cdev[0]->handler = lcs_irq; | 2074 | ccwgdev->cdev[0]->handler = lcs_irq; |
2086 | ccwgdev->cdev[1]->handler = lcs_irq; | 2075 | ccwgdev->cdev[1]->handler = lcs_irq; |
@@ -2089,7 +2078,9 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) | |||
2089 | card->thread_start_mask = 0; | 2078 | card->thread_start_mask = 0; |
2090 | card->thread_allowed_mask = 0; | 2079 | card->thread_allowed_mask = 0; |
2091 | card->thread_running_mask = 0; | 2080 | card->thread_running_mask = 0; |
2092 | return 0; | 2081 | ccwgdev->dev.type = &lcs_devtype; |
2082 | |||
2083 | return 0; | ||
2093 | } | 2084 | } |
2094 | 2085 | ||
2095 | static int | 2086 | static int |
@@ -2172,12 +2163,6 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) | |||
2172 | dev = alloc_etherdev(0); | 2163 | dev = alloc_etherdev(0); |
2173 | break; | 2164 | break; |
2174 | #endif | 2165 | #endif |
2175 | #ifdef CONFIG_TR | ||
2176 | case LCS_FRAME_TYPE_TR: | ||
2177 | card->lan_type_trans = tr_type_trans; | ||
2178 | dev = alloc_trdev(0); | ||
2179 | break; | ||
2180 | #endif | ||
2181 | #ifdef CONFIG_FDDI | 2166 | #ifdef CONFIG_FDDI |
2182 | case LCS_FRAME_TYPE_FDDI: | 2167 | case LCS_FRAME_TYPE_FDDI: |
2183 | card->lan_type_trans = fddi_type_trans; | 2168 | card->lan_type_trans = fddi_type_trans; |
@@ -2323,9 +2308,9 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev) | |||
2323 | } | 2308 | } |
2324 | if (card->dev) | 2309 | if (card->dev) |
2325 | unregister_netdev(card->dev); | 2310 | unregister_netdev(card->dev); |
2326 | sysfs_remove_group(&ccwgdev->dev.kobj, &lcs_attr_group); | ||
2327 | lcs_cleanup_card(card); | 2311 | lcs_cleanup_card(card); |
2328 | lcs_free_card(card); | 2312 | lcs_free_card(card); |
2313 | dev_set_drvdata(&ccwgdev->dev, NULL); | ||
2329 | put_device(&ccwgdev->dev); | 2314 | put_device(&ccwgdev->dev); |
2330 | } | 2315 | } |
2331 | 2316 | ||
@@ -2410,9 +2395,7 @@ static struct ccwgroup_driver lcs_group_driver = { | |||
2410 | .owner = THIS_MODULE, | 2395 | .owner = THIS_MODULE, |
2411 | .name = "lcs", | 2396 | .name = "lcs", |
2412 | }, | 2397 | }, |
2413 | .max_slaves = 2, | 2398 | .setup = lcs_probe_device, |
2414 | .driver_id = 0xD3C3E2, | ||
2415 | .probe = lcs_probe_device, | ||
2416 | .remove = lcs_remove_device, | 2399 | .remove = lcs_remove_device, |
2417 | .set_online = lcs_new_device, | 2400 | .set_online = lcs_new_device, |
2418 | .set_offline = lcs_shutdown_device, | 2401 | .set_offline = lcs_shutdown_device, |
@@ -2423,30 +2406,24 @@ static struct ccwgroup_driver lcs_group_driver = { | |||
2423 | .restore = lcs_restore, | 2406 | .restore = lcs_restore, |
2424 | }; | 2407 | }; |
2425 | 2408 | ||
2426 | static ssize_t | 2409 | static ssize_t lcs_driver_group_store(struct device_driver *ddrv, |
2427 | lcs_driver_group_store(struct device_driver *ddrv, const char *buf, | 2410 | const char *buf, size_t count) |
2428 | size_t count) | ||
2429 | { | 2411 | { |
2430 | int err; | 2412 | int err; |
2431 | err = ccwgroup_create_from_string(lcs_root_dev, | 2413 | err = ccwgroup_create_dev(lcs_root_dev, &lcs_group_driver, 2, buf); |
2432 | lcs_group_driver.driver_id, | ||
2433 | &lcs_ccw_driver, 2, buf); | ||
2434 | return err ? err : count; | 2414 | return err ? err : count; |
2435 | } | 2415 | } |
2436 | |||
2437 | static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store); | 2416 | static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store); |
2438 | 2417 | ||
2439 | static struct attribute *lcs_group_attrs[] = { | 2418 | static struct attribute *lcs_drv_attrs[] = { |
2440 | &driver_attr_group.attr, | 2419 | &driver_attr_group.attr, |
2441 | NULL, | 2420 | NULL, |
2442 | }; | 2421 | }; |
2443 | 2422 | static struct attribute_group lcs_drv_attr_group = { | |
2444 | static struct attribute_group lcs_group_attr_group = { | 2423 | .attrs = lcs_drv_attrs, |
2445 | .attrs = lcs_group_attrs, | ||
2446 | }; | 2424 | }; |
2447 | 2425 | static const struct attribute_group *lcs_drv_attr_groups[] = { | |
2448 | static const struct attribute_group *lcs_group_attr_groups[] = { | 2426 | &lcs_drv_attr_group, |
2449 | &lcs_group_attr_group, | ||
2450 | NULL, | 2427 | NULL, |
2451 | }; | 2428 | }; |
2452 | 2429 | ||
@@ -2470,7 +2447,7 @@ __init lcs_init_module(void) | |||
2470 | rc = ccw_driver_register(&lcs_ccw_driver); | 2447 | rc = ccw_driver_register(&lcs_ccw_driver); |
2471 | if (rc) | 2448 | if (rc) |
2472 | goto ccw_err; | 2449 | goto ccw_err; |
2473 | lcs_group_driver.driver.groups = lcs_group_attr_groups; | 2450 | lcs_group_driver.driver.groups = lcs_drv_attr_groups; |
2474 | rc = ccwgroup_driver_register(&lcs_group_driver); | 2451 | rc = ccwgroup_driver_register(&lcs_group_driver); |
2475 | if (rc) | 2452 | if (rc) |
2476 | goto ccwgroup_err; | 2453 | goto ccwgroup_err; |
@@ -2496,8 +2473,6 @@ __exit lcs_cleanup_module(void) | |||
2496 | { | 2473 | { |
2497 | pr_info("Terminating lcs module.\n"); | 2474 | pr_info("Terminating lcs module.\n"); |
2498 | LCS_DBF_TEXT(0, trace, "cleanup"); | 2475 | LCS_DBF_TEXT(0, trace, "cleanup"); |
2499 | driver_remove_file(&lcs_group_driver.driver, | ||
2500 | &driver_attr_group); | ||
2501 | ccwgroup_driver_unregister(&lcs_group_driver); | 2476 | ccwgroup_driver_unregister(&lcs_group_driver); |
2502 | ccw_driver_unregister(&lcs_ccw_driver); | 2477 | ccw_driver_unregister(&lcs_ccw_driver); |
2503 | 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 ec7921b5138e..06e8f31ff3dc 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
@@ -13,8 +13,6 @@ | |||
13 | 13 | ||
14 | #include <linux/if.h> | 14 | #include <linux/if.h> |
15 | #include <linux/if_arp.h> | 15 | #include <linux/if_arp.h> |
16 | #include <linux/if_tr.h> | ||
17 | #include <linux/trdevice.h> | ||
18 | #include <linux/etherdevice.h> | 16 | #include <linux/etherdevice.h> |
19 | #include <linux/if_vlan.h> | 17 | #include <linux/if_vlan.h> |
20 | #include <linux/ctype.h> | 18 | #include <linux/ctype.h> |
@@ -676,8 +674,6 @@ struct qeth_card_options { | |||
676 | struct qeth_ipa_info adp; /*Adapter parameters*/ | 674 | struct qeth_ipa_info adp; /*Adapter parameters*/ |
677 | struct qeth_routing_info route6; | 675 | struct qeth_routing_info route6; |
678 | struct qeth_ipa_info ipa6; | 676 | struct qeth_ipa_info ipa6; |
679 | int broadcast_mode; | ||
680 | int macaddr_mode; | ||
681 | int fake_broadcast; | 677 | int fake_broadcast; |
682 | int add_hhlen; | 678 | int add_hhlen; |
683 | int layer2; | 679 | int layer2; |
@@ -711,7 +707,16 @@ struct qeth_discipline { | |||
711 | qdio_handler_t *input_handler; | 707 | qdio_handler_t *input_handler; |
712 | qdio_handler_t *output_handler; | 708 | qdio_handler_t *output_handler; |
713 | int (*recover)(void *ptr); | 709 | int (*recover)(void *ptr); |
714 | 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 *); | ||
715 | }; | 720 | }; |
716 | 721 | ||
717 | struct qeth_vlan_vid { | 722 | struct qeth_vlan_vid { |
@@ -775,7 +780,7 @@ struct qeth_card { | |||
775 | struct qeth_perf_stats perf_stats; | 780 | struct qeth_perf_stats perf_stats; |
776 | int read_or_write_problem; | 781 | int read_or_write_problem; |
777 | struct qeth_osn_info osn_info; | 782 | struct qeth_osn_info osn_info; |
778 | struct qeth_discipline discipline; | 783 | struct qeth_discipline *discipline; |
779 | atomic_t force_alloc_skb; | 784 | atomic_t force_alloc_skb; |
780 | struct service_level qeth_service_level; | 785 | struct service_level qeth_service_level; |
781 | struct qdio_ssqd_desc ssqd; | 786 | struct qdio_ssqd_desc ssqd; |
@@ -841,16 +846,15 @@ static inline int qeth_is_diagass_supported(struct qeth_card *card, | |||
841 | return card->info.diagass_support & (__u32)cmd; | 846 | return card->info.diagass_support & (__u32)cmd; |
842 | } | 847 | } |
843 | 848 | ||
844 | extern struct ccwgroup_driver qeth_l2_ccwgroup_driver; | 849 | extern struct qeth_discipline qeth_l2_discipline; |
845 | 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 | |||
846 | const char *qeth_get_cardname_short(struct qeth_card *); | 854 | const char *qeth_get_cardname_short(struct qeth_card *); |
847 | int qeth_realloc_buffer_pool(struct qeth_card *, int); | 855 | int qeth_realloc_buffer_pool(struct qeth_card *, int); |
848 | 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); |
849 | void qeth_core_free_discipline(struct qeth_card *); | 857 | void qeth_core_free_discipline(struct qeth_card *); |
850 | int qeth_core_create_device_attributes(struct device *); | ||
851 | void qeth_core_remove_device_attributes(struct device *); | ||
852 | int qeth_core_create_osn_attributes(struct device *); | ||
853 | void qeth_core_remove_osn_attributes(struct device *); | ||
854 | void qeth_buffer_reclaim_work(struct work_struct *); | 858 | void qeth_buffer_reclaim_work(struct work_struct *); |
855 | 859 | ||
856 | /* 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 120955c66410..e118e1e1e1c1 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -1329,8 +1329,6 @@ static void qeth_set_intial_options(struct qeth_card *card) | |||
1329 | { | 1329 | { |
1330 | card->options.route4.type = NO_ROUTER; | 1330 | card->options.route4.type = NO_ROUTER; |
1331 | card->options.route6.type = NO_ROUTER; | 1331 | card->options.route6.type = NO_ROUTER; |
1332 | card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; | ||
1333 | card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL; | ||
1334 | card->options.fake_broadcast = 0; | 1332 | card->options.fake_broadcast = 0; |
1335 | card->options.add_hhlen = DEFAULT_ADD_HHLEN; | 1333 | card->options.add_hhlen = DEFAULT_ADD_HHLEN; |
1336 | card->options.performance_stats = 0; | 1334 | card->options.performance_stats = 0; |
@@ -1365,7 +1363,7 @@ static void qeth_start_kernel_thread(struct work_struct *work) | |||
1365 | card->write.state != CH_STATE_UP) | 1363 | card->write.state != CH_STATE_UP) |
1366 | return; | 1364 | return; |
1367 | if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) { | 1365 | if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) { |
1368 | ts = kthread_run(card->discipline.recover, (void *)card, | 1366 | ts = kthread_run(card->discipline->recover, (void *)card, |
1369 | "qeth_recover"); | 1367 | "qeth_recover"); |
1370 | if (IS_ERR(ts)) { | 1368 | if (IS_ERR(ts)) { |
1371 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); | 1369 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); |
@@ -1672,7 +1670,8 @@ static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd) | |||
1672 | { | 1670 | { |
1673 | QETH_DBF_TEXT(SETUP, 2, "cfgblkt"); | 1671 | QETH_DBF_TEXT(SETUP, 2, "cfgblkt"); |
1674 | 1672 | ||
1675 | if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) { | 1673 | if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && |
1674 | (prcd[76] == 0xF5 || prcd[76] == 0xF6)) { | ||
1676 | card->info.blkt.time_total = 250; | 1675 | card->info.blkt.time_total = 250; |
1677 | card->info.blkt.inter_packet = 5; | 1676 | card->info.blkt.inter_packet = 5; |
1678 | card->info.blkt.inter_packet_jumbo = 15; | 1677 | card->info.blkt.inter_packet_jumbo = 15; |
@@ -3338,7 +3337,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, | |||
3338 | if (rc) { | 3337 | if (rc) { |
3339 | queue->card->stats.tx_errors += count; | 3338 | queue->card->stats.tx_errors += count; |
3340 | /* ignore temporary SIGA errors without busy condition */ | 3339 | /* ignore temporary SIGA errors without busy condition */ |
3341 | if (rc == QDIO_ERROR_SIGA_TARGET) | 3340 | if (rc == -ENOBUFS) |
3342 | return; | 3341 | return; |
3343 | QETH_CARD_TEXT(queue->card, 2, "flushbuf"); | 3342 | QETH_CARD_TEXT(queue->card, 2, "flushbuf"); |
3344 | QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no); | 3343 | QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no); |
@@ -3532,7 +3531,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, | |||
3532 | int i; | 3531 | int i; |
3533 | 3532 | ||
3534 | QETH_CARD_TEXT(card, 6, "qdouhdl"); | 3533 | QETH_CARD_TEXT(card, 6, "qdouhdl"); |
3535 | if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { | 3534 | if (qdio_error & QDIO_ERROR_FATAL) { |
3536 | QETH_CARD_TEXT(card, 2, "achkcond"); | 3535 | QETH_CARD_TEXT(card, 2, "achkcond"); |
3537 | netif_stop_queue(card->dev); | 3536 | netif_stop_queue(card->dev); |
3538 | qeth_schedule_recovery(card); | 3537 | qeth_schedule_recovery(card); |
@@ -4540,7 +4539,8 @@ static void qeth_determine_capabilities(struct qeth_card *card) | |||
4540 | goto out_offline; | 4539 | goto out_offline; |
4541 | } | 4540 | } |
4542 | qeth_configure_unitaddr(card, prcd); | 4541 | qeth_configure_unitaddr(card, prcd); |
4543 | qeth_configure_blkt_default(card, prcd); | 4542 | if (ddev_offline) |
4543 | qeth_configure_blkt_default(card, prcd); | ||
4544 | kfree(prcd); | 4544 | kfree(prcd); |
4545 | 4545 | ||
4546 | rc = qdio_get_ssqd_desc(ddev, &card->ssqd); | 4546 | rc = qdio_get_ssqd_desc(ddev, &card->ssqd); |
@@ -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; |
@@ -4909,11 +4902,7 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card, | |||
4909 | break; | 4902 | break; |
4910 | case QETH_HEADER_TYPE_LAYER3: | 4903 | case QETH_HEADER_TYPE_LAYER3: |
4911 | skb_len = (*hdr)->hdr.l3.length; | 4904 | skb_len = (*hdr)->hdr.l3.length; |
4912 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || | 4905 | headroom = ETH_HLEN; |
4913 | (card->info.link_type == QETH_LINK_TYPE_HSTR)) | ||
4914 | headroom = TR_HLEN; | ||
4915 | else | ||
4916 | headroom = ETH_HLEN; | ||
4917 | break; | 4906 | break; |
4918 | case QETH_HEADER_TYPE_OSN: | 4907 | case QETH_HEADER_TYPE_OSN: |
4919 | skb_len = (*hdr)->hdr.osn.pdu_length; | 4908 | skb_len = (*hdr)->hdr.osn.pdu_length; |
@@ -5044,17 +5033,15 @@ int qeth_core_load_discipline(struct qeth_card *card, | |||
5044 | mutex_lock(&qeth_mod_mutex); | 5033 | mutex_lock(&qeth_mod_mutex); |
5045 | switch (discipline) { | 5034 | switch (discipline) { |
5046 | case QETH_DISCIPLINE_LAYER3: | 5035 | case QETH_DISCIPLINE_LAYER3: |
5047 | card->discipline.ccwgdriver = try_then_request_module( | 5036 | card->discipline = try_then_request_module( |
5048 | symbol_get(qeth_l3_ccwgroup_driver), | 5037 | symbol_get(qeth_l3_discipline), "qeth_l3"); |
5049 | "qeth_l3"); | ||
5050 | break; | 5038 | break; |
5051 | case QETH_DISCIPLINE_LAYER2: | 5039 | case QETH_DISCIPLINE_LAYER2: |
5052 | card->discipline.ccwgdriver = try_then_request_module( | 5040 | card->discipline = try_then_request_module( |
5053 | symbol_get(qeth_l2_ccwgroup_driver), | 5041 | symbol_get(qeth_l2_discipline), "qeth_l2"); |
5054 | "qeth_l2"); | ||
5055 | break; | 5042 | break; |
5056 | } | 5043 | } |
5057 | if (!card->discipline.ccwgdriver) { | 5044 | if (!card->discipline) { |
5058 | dev_err(&card->gdev->dev, "There is no kernel module to " | 5045 | dev_err(&card->gdev->dev, "There is no kernel module to " |
5059 | "support discipline %d\n", discipline); | 5046 | "support discipline %d\n", discipline); |
5060 | rc = -EINVAL; | 5047 | rc = -EINVAL; |
@@ -5066,12 +5053,21 @@ int qeth_core_load_discipline(struct qeth_card *card, | |||
5066 | void qeth_core_free_discipline(struct qeth_card *card) | 5053 | void qeth_core_free_discipline(struct qeth_card *card) |
5067 | { | 5054 | { |
5068 | if (card->options.layer2) | 5055 | if (card->options.layer2) |
5069 | symbol_put(qeth_l2_ccwgroup_driver); | 5056 | symbol_put(qeth_l2_discipline); |
5070 | else | 5057 | else |
5071 | symbol_put(qeth_l3_ccwgroup_driver); | 5058 | symbol_put(qeth_l3_discipline); |
5072 | card->discipline.ccwgdriver = NULL; | 5059 | card->discipline = NULL; |
5073 | } | 5060 | } |
5074 | 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 | |||
5075 | static int qeth_core_probe_device(struct ccwgroup_device *gdev) | 5071 | static int qeth_core_probe_device(struct ccwgroup_device *gdev) |
5076 | { | 5072 | { |
5077 | struct qeth_card *card; | 5073 | struct qeth_card *card; |
@@ -5126,18 +5122,17 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) | |||
5126 | } | 5122 | } |
5127 | 5123 | ||
5128 | if (card->info.type == QETH_CARD_TYPE_OSN) | 5124 | if (card->info.type == QETH_CARD_TYPE_OSN) |
5129 | rc = qeth_core_create_osn_attributes(dev); | 5125 | gdev->dev.type = &qeth_osn_devtype; |
5130 | else | 5126 | else |
5131 | rc = qeth_core_create_device_attributes(dev); | 5127 | gdev->dev.type = &qeth_generic_devtype; |
5132 | if (rc) | 5128 | |
5133 | goto err_dbf; | ||
5134 | switch (card->info.type) { | 5129 | switch (card->info.type) { |
5135 | case QETH_CARD_TYPE_OSN: | 5130 | case QETH_CARD_TYPE_OSN: |
5136 | case QETH_CARD_TYPE_OSM: | 5131 | case QETH_CARD_TYPE_OSM: |
5137 | rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); | 5132 | rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); |
5138 | if (rc) | 5133 | if (rc) |
5139 | goto err_attr; | 5134 | goto err_dbf; |
5140 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 5135 | rc = card->discipline->setup(card->gdev); |
5141 | if (rc) | 5136 | if (rc) |
5142 | goto err_disc; | 5137 | goto err_disc; |
5143 | case QETH_CARD_TYPE_OSD: | 5138 | case QETH_CARD_TYPE_OSD: |
@@ -5155,11 +5150,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) | |||
5155 | 5150 | ||
5156 | err_disc: | 5151 | err_disc: |
5157 | qeth_core_free_discipline(card); | 5152 | qeth_core_free_discipline(card); |
5158 | err_attr: | ||
5159 | if (card->info.type == QETH_CARD_TYPE_OSN) | ||
5160 | qeth_core_remove_osn_attributes(dev); | ||
5161 | else | ||
5162 | qeth_core_remove_device_attributes(dev); | ||
5163 | err_dbf: | 5153 | err_dbf: |
5164 | debug_unregister(card->debug); | 5154 | debug_unregister(card->debug); |
5165 | err_card: | 5155 | err_card: |
@@ -5176,14 +5166,8 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) | |||
5176 | 5166 | ||
5177 | QETH_DBF_TEXT(SETUP, 2, "removedv"); | 5167 | QETH_DBF_TEXT(SETUP, 2, "removedv"); |
5178 | 5168 | ||
5179 | if (card->info.type == QETH_CARD_TYPE_OSN) { | 5169 | if (card->discipline) { |
5180 | qeth_core_remove_osn_attributes(&gdev->dev); | 5170 | card->discipline->remove(gdev); |
5181 | } else { | ||
5182 | qeth_core_remove_device_attributes(&gdev->dev); | ||
5183 | } | ||
5184 | |||
5185 | if (card->discipline.ccwgdriver) { | ||
5186 | card->discipline.ccwgdriver->remove(gdev); | ||
5187 | qeth_core_free_discipline(card); | 5171 | qeth_core_free_discipline(card); |
5188 | } | 5172 | } |
5189 | 5173 | ||
@@ -5203,7 +5187,7 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) | |||
5203 | int rc = 0; | 5187 | int rc = 0; |
5204 | int def_discipline; | 5188 | int def_discipline; |
5205 | 5189 | ||
5206 | if (!card->discipline.ccwgdriver) { | 5190 | if (!card->discipline) { |
5207 | if (card->info.type == QETH_CARD_TYPE_IQD) | 5191 | if (card->info.type == QETH_CARD_TYPE_IQD) |
5208 | def_discipline = QETH_DISCIPLINE_LAYER3; | 5192 | def_discipline = QETH_DISCIPLINE_LAYER3; |
5209 | else | 5193 | else |
@@ -5211,11 +5195,11 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) | |||
5211 | rc = qeth_core_load_discipline(card, def_discipline); | 5195 | rc = qeth_core_load_discipline(card, def_discipline); |
5212 | if (rc) | 5196 | if (rc) |
5213 | goto err; | 5197 | goto err; |
5214 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 5198 | rc = card->discipline->setup(card->gdev); |
5215 | if (rc) | 5199 | if (rc) |
5216 | goto err; | 5200 | goto err; |
5217 | } | 5201 | } |
5218 | rc = card->discipline.ccwgdriver->set_online(gdev); | 5202 | rc = card->discipline->set_online(gdev); |
5219 | err: | 5203 | err: |
5220 | return rc; | 5204 | return rc; |
5221 | } | 5205 | } |
@@ -5223,58 +5207,52 @@ err: | |||
5223 | static int qeth_core_set_offline(struct ccwgroup_device *gdev) | 5207 | static int qeth_core_set_offline(struct ccwgroup_device *gdev) |
5224 | { | 5208 | { |
5225 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5209 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5226 | return card->discipline.ccwgdriver->set_offline(gdev); | 5210 | return card->discipline->set_offline(gdev); |
5227 | } | 5211 | } |
5228 | 5212 | ||
5229 | static void qeth_core_shutdown(struct ccwgroup_device *gdev) | 5213 | static void qeth_core_shutdown(struct ccwgroup_device *gdev) |
5230 | { | 5214 | { |
5231 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5215 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5232 | if (card->discipline.ccwgdriver && | 5216 | if (card->discipline && card->discipline->shutdown) |
5233 | card->discipline.ccwgdriver->shutdown) | 5217 | card->discipline->shutdown(gdev); |
5234 | card->discipline.ccwgdriver->shutdown(gdev); | ||
5235 | } | 5218 | } |
5236 | 5219 | ||
5237 | static int qeth_core_prepare(struct ccwgroup_device *gdev) | 5220 | static int qeth_core_prepare(struct ccwgroup_device *gdev) |
5238 | { | 5221 | { |
5239 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5222 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5240 | if (card->discipline.ccwgdriver && | 5223 | if (card->discipline && card->discipline->prepare) |
5241 | card->discipline.ccwgdriver->prepare) | 5224 | return card->discipline->prepare(gdev); |
5242 | return card->discipline.ccwgdriver->prepare(gdev); | ||
5243 | return 0; | 5225 | return 0; |
5244 | } | 5226 | } |
5245 | 5227 | ||
5246 | static void qeth_core_complete(struct ccwgroup_device *gdev) | 5228 | static void qeth_core_complete(struct ccwgroup_device *gdev) |
5247 | { | 5229 | { |
5248 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5230 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5249 | if (card->discipline.ccwgdriver && | 5231 | if (card->discipline && card->discipline->complete) |
5250 | card->discipline.ccwgdriver->complete) | 5232 | card->discipline->complete(gdev); |
5251 | card->discipline.ccwgdriver->complete(gdev); | ||
5252 | } | 5233 | } |
5253 | 5234 | ||
5254 | static int qeth_core_freeze(struct ccwgroup_device *gdev) | 5235 | static int qeth_core_freeze(struct ccwgroup_device *gdev) |
5255 | { | 5236 | { |
5256 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5237 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5257 | if (card->discipline.ccwgdriver && | 5238 | if (card->discipline && card->discipline->freeze) |
5258 | card->discipline.ccwgdriver->freeze) | 5239 | return card->discipline->freeze(gdev); |
5259 | return card->discipline.ccwgdriver->freeze(gdev); | ||
5260 | return 0; | 5240 | return 0; |
5261 | } | 5241 | } |
5262 | 5242 | ||
5263 | static int qeth_core_thaw(struct ccwgroup_device *gdev) | 5243 | static int qeth_core_thaw(struct ccwgroup_device *gdev) |
5264 | { | 5244 | { |
5265 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5245 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5266 | if (card->discipline.ccwgdriver && | 5246 | if (card->discipline && card->discipline->thaw) |
5267 | card->discipline.ccwgdriver->thaw) | 5247 | return card->discipline->thaw(gdev); |
5268 | return card->discipline.ccwgdriver->thaw(gdev); | ||
5269 | return 0; | 5248 | return 0; |
5270 | } | 5249 | } |
5271 | 5250 | ||
5272 | static int qeth_core_restore(struct ccwgroup_device *gdev) | 5251 | static int qeth_core_restore(struct ccwgroup_device *gdev) |
5273 | { | 5252 | { |
5274 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 5253 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
5275 | if (card->discipline.ccwgdriver && | 5254 | if (card->discipline && card->discipline->restore) |
5276 | card->discipline.ccwgdriver->restore) | 5255 | return card->discipline->restore(gdev); |
5277 | return card->discipline.ccwgdriver->restore(gdev); | ||
5278 | return 0; | 5256 | return 0; |
5279 | } | 5257 | } |
5280 | 5258 | ||
@@ -5283,8 +5261,7 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = { | |||
5283 | .owner = THIS_MODULE, | 5261 | .owner = THIS_MODULE, |
5284 | .name = "qeth", | 5262 | .name = "qeth", |
5285 | }, | 5263 | }, |
5286 | .driver_id = 0xD8C5E3C8, | 5264 | .setup = qeth_core_probe_device, |
5287 | .probe = qeth_core_probe_device, | ||
5288 | .remove = qeth_core_remove_device, | 5265 | .remove = qeth_core_remove_device, |
5289 | .set_online = qeth_core_set_online, | 5266 | .set_online = qeth_core_set_online, |
5290 | .set_offline = qeth_core_set_offline, | 5267 | .set_offline = qeth_core_set_offline, |
@@ -5296,21 +5273,30 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = { | |||
5296 | .restore = qeth_core_restore, | 5273 | .restore = qeth_core_restore, |
5297 | }; | 5274 | }; |
5298 | 5275 | ||
5299 | static ssize_t | 5276 | static ssize_t qeth_core_driver_group_store(struct device_driver *ddrv, |
5300 | qeth_core_driver_group_store(struct device_driver *ddrv, const char *buf, | 5277 | const char *buf, size_t count) |
5301 | size_t count) | ||
5302 | { | 5278 | { |
5303 | int err; | 5279 | int err; |
5304 | err = qeth_core_driver_group(buf, qeth_core_root_dev, | ||
5305 | qeth_core_ccwgroup_driver.driver_id); | ||
5306 | if (err) | ||
5307 | return err; | ||
5308 | else | ||
5309 | return count; | ||
5310 | } | ||
5311 | 5280 | ||
5281 | err = ccwgroup_create_dev(qeth_core_root_dev, | ||
5282 | &qeth_core_ccwgroup_driver, 3, buf); | ||
5283 | |||
5284 | return err ? err : count; | ||
5285 | } | ||
5312 | static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store); | 5286 | static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store); |
5313 | 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 | |||
5314 | static struct { | 5300 | static struct { |
5315 | const char str[ETH_GSTRING_LEN]; | 5301 | const char str[ETH_GSTRING_LEN]; |
5316 | } qeth_ethtool_stats_keys[] = { | 5302 | } qeth_ethtool_stats_keys[] = { |
@@ -5548,49 +5534,41 @@ static int __init qeth_core_init(void) | |||
5548 | rc = qeth_register_dbf_views(); | 5534 | rc = qeth_register_dbf_views(); |
5549 | if (rc) | 5535 | if (rc) |
5550 | goto out_err; | 5536 | goto out_err; |
5551 | rc = ccw_driver_register(&qeth_ccw_driver); | ||
5552 | if (rc) | ||
5553 | goto ccw_err; | ||
5554 | rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver); | ||
5555 | if (rc) | ||
5556 | goto ccwgroup_err; | ||
5557 | rc = driver_create_file(&qeth_core_ccwgroup_driver.driver, | ||
5558 | &driver_attr_group); | ||
5559 | if (rc) | ||
5560 | goto driver_err; | ||
5561 | qeth_core_root_dev = root_device_register("qeth"); | 5537 | qeth_core_root_dev = root_device_register("qeth"); |
5562 | 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; |
5563 | if (rc) | 5539 | if (rc) |
5564 | goto register_err; | 5540 | goto register_err; |
5565 | |||
5566 | qeth_core_header_cache = kmem_cache_create("qeth_hdr", | 5541 | qeth_core_header_cache = kmem_cache_create("qeth_hdr", |
5567 | sizeof(struct qeth_hdr) + ETH_HLEN, 64, 0, NULL); | 5542 | sizeof(struct qeth_hdr) + ETH_HLEN, 64, 0, NULL); |
5568 | if (!qeth_core_header_cache) { | 5543 | if (!qeth_core_header_cache) { |
5569 | rc = -ENOMEM; | 5544 | rc = -ENOMEM; |
5570 | goto slab_err; | 5545 | goto slab_err; |
5571 | } | 5546 | } |
5572 | |||
5573 | qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf", | 5547 | qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf", |
5574 | sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL); | 5548 | sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL); |
5575 | if (!qeth_qdio_outbuf_cache) { | 5549 | if (!qeth_qdio_outbuf_cache) { |
5576 | rc = -ENOMEM; | 5550 | rc = -ENOMEM; |
5577 | goto cqslab_err; | 5551 | goto cqslab_err; |
5578 | } | 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; | ||
5579 | 5560 | ||
5580 | 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); | ||
5581 | cqslab_err: | 5567 | cqslab_err: |
5582 | kmem_cache_destroy(qeth_core_header_cache); | 5568 | kmem_cache_destroy(qeth_core_header_cache); |
5583 | slab_err: | 5569 | slab_err: |
5584 | root_device_unregister(qeth_core_root_dev); | 5570 | root_device_unregister(qeth_core_root_dev); |
5585 | register_err: | 5571 | register_err: |
5586 | driver_remove_file(&qeth_core_ccwgroup_driver.driver, | ||
5587 | &driver_attr_group); | ||
5588 | driver_err: | ||
5589 | ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); | ||
5590 | ccwgroup_err: | ||
5591 | ccw_driver_unregister(&qeth_ccw_driver); | ||
5592 | ccw_err: | ||
5593 | QETH_DBF_MESSAGE(2, "Initialization failed with code %d\n", rc); | ||
5594 | qeth_unregister_dbf_views(); | 5572 | qeth_unregister_dbf_views(); |
5595 | out_err: | 5573 | out_err: |
5596 | pr_err("Initializing the qeth device driver failed\n"); | 5574 | pr_err("Initializing the qeth device driver failed\n"); |
@@ -5599,13 +5577,11 @@ out_err: | |||
5599 | 5577 | ||
5600 | static void __exit qeth_core_exit(void) | 5578 | static void __exit qeth_core_exit(void) |
5601 | { | 5579 | { |
5602 | root_device_unregister(qeth_core_root_dev); | ||
5603 | driver_remove_file(&qeth_core_ccwgroup_driver.driver, | ||
5604 | &driver_attr_group); | ||
5605 | ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); | 5580 | ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); |
5606 | ccw_driver_unregister(&qeth_ccw_driver); | 5581 | ccw_driver_unregister(&qeth_ccw_driver); |
5607 | kmem_cache_destroy(qeth_qdio_outbuf_cache); | 5582 | kmem_cache_destroy(qeth_qdio_outbuf_cache); |
5608 | kmem_cache_destroy(qeth_core_header_cache); | 5583 | kmem_cache_destroy(qeth_core_header_cache); |
5584 | root_device_unregister(qeth_core_root_dev); | ||
5609 | qeth_unregister_dbf_views(); | 5585 | qeth_unregister_dbf_views(); |
5610 | pr_info("core functions removed\n"); | 5586 | pr_info("core functions removed\n"); |
5611 | } | 5587 | } |
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index ff41e42004ac..a11b30c38423 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h | |||
@@ -70,16 +70,6 @@ enum qeth_link_types { | |||
70 | QETH_LINK_TYPE_ATM_NATIVE = 0x90, | 70 | QETH_LINK_TYPE_ATM_NATIVE = 0x90, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | enum qeth_tr_macaddr_modes { | ||
74 | QETH_TR_MACADDR_NONCANONICAL = 0, | ||
75 | QETH_TR_MACADDR_CANONICAL = 1, | ||
76 | }; | ||
77 | |||
78 | enum qeth_tr_broadcast_modes { | ||
79 | QETH_TR_BROADCAST_ALLRINGS = 0, | ||
80 | QETH_TR_BROADCAST_LOCAL = 1, | ||
81 | }; | ||
82 | |||
83 | /* | 73 | /* |
84 | * Routing stuff | 74 | * Routing stuff |
85 | */ | 75 | */ |
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 f85921607686..7be5e9775691 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -976,57 +976,6 @@ static inline u8 qeth_l3_get_qeth_hdr_flags6(int cast_type) | |||
976 | return ct | QETH_CAST_UNICAST; | 976 | return ct | QETH_CAST_UNICAST; |
977 | } | 977 | } |
978 | 978 | ||
979 | static int qeth_l3_send_setadp_mode(struct qeth_card *card, __u32 command, | ||
980 | __u32 mode) | ||
981 | { | ||
982 | int rc; | ||
983 | struct qeth_cmd_buffer *iob; | ||
984 | struct qeth_ipa_cmd *cmd; | ||
985 | |||
986 | QETH_CARD_TEXT(card, 4, "adpmode"); | ||
987 | |||
988 | iob = qeth_get_adapter_cmd(card, command, | ||
989 | sizeof(struct qeth_ipacmd_setadpparms)); | ||
990 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | ||
991 | cmd->data.setadapterparms.data.mode = mode; | ||
992 | rc = qeth_send_ipa_cmd(card, iob, qeth_default_setadapterparms_cb, | ||
993 | NULL); | ||
994 | return rc; | ||
995 | } | ||
996 | |||
997 | static int qeth_l3_setadapter_hstr(struct qeth_card *card) | ||
998 | { | ||
999 | int rc; | ||
1000 | |||
1001 | QETH_CARD_TEXT(card, 4, "adphstr"); | ||
1002 | |||
1003 | if (qeth_adp_supported(card, IPA_SETADP_SET_BROADCAST_MODE)) { | ||
1004 | rc = qeth_l3_send_setadp_mode(card, | ||
1005 | IPA_SETADP_SET_BROADCAST_MODE, | ||
1006 | card->options.broadcast_mode); | ||
1007 | if (rc) | ||
1008 | QETH_DBF_MESSAGE(2, "couldn't set broadcast mode on " | ||
1009 | "device %s: x%x\n", | ||
1010 | CARD_BUS_ID(card), rc); | ||
1011 | rc = qeth_l3_send_setadp_mode(card, | ||
1012 | IPA_SETADP_ALTER_MAC_ADDRESS, | ||
1013 | card->options.macaddr_mode); | ||
1014 | if (rc) | ||
1015 | QETH_DBF_MESSAGE(2, "couldn't set macaddr mode on " | ||
1016 | "device %s: x%x\n", CARD_BUS_ID(card), rc); | ||
1017 | return rc; | ||
1018 | } | ||
1019 | if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL) | ||
1020 | QETH_DBF_MESSAGE(2, "set adapter parameters not available " | ||
1021 | "to set broadcast mode, using ALLRINGS " | ||
1022 | "on device %s:\n", CARD_BUS_ID(card)); | ||
1023 | if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL) | ||
1024 | QETH_DBF_MESSAGE(2, "set adapter parameters not available " | ||
1025 | "to set macaddr mode, using NONCANONICAL " | ||
1026 | "on device %s:\n", CARD_BUS_ID(card)); | ||
1027 | return 0; | ||
1028 | } | ||
1029 | |||
1030 | static int qeth_l3_setadapter_parms(struct qeth_card *card) | 979 | static int qeth_l3_setadapter_parms(struct qeth_card *card) |
1031 | { | 980 | { |
1032 | int rc; | 981 | int rc; |
@@ -1052,10 +1001,6 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card) | |||
1052 | " address failed\n"); | 1001 | " address failed\n"); |
1053 | } | 1002 | } |
1054 | 1003 | ||
1055 | if ((card->info.link_type == QETH_LINK_TYPE_HSTR) || | ||
1056 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR)) | ||
1057 | rc = qeth_l3_setadapter_hstr(card); | ||
1058 | |||
1059 | return rc; | 1004 | return rc; |
1060 | } | 1005 | } |
1061 | 1006 | ||
@@ -1671,10 +1616,7 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd) | |||
1671 | static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac, | 1616 | static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac, |
1672 | struct net_device *dev) | 1617 | struct net_device *dev) |
1673 | { | 1618 | { |
1674 | if (dev->type == ARPHRD_IEEE802_TR) | 1619 | ip_eth_mc_map(ipm, mac); |
1675 | ip_tr_mc_map(ipm, mac); | ||
1676 | else | ||
1677 | ip_eth_mc_map(ipm, mac); | ||
1678 | } | 1620 | } |
1679 | 1621 | ||
1680 | static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev) | 1622 | static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev) |
@@ -1922,8 +1864,6 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card, | |||
1922 | #endif | 1864 | #endif |
1923 | case __constant_htons(ETH_P_IP): | 1865 | case __constant_htons(ETH_P_IP): |
1924 | ip_hdr = (struct iphdr *)skb->data; | 1866 | ip_hdr = (struct iphdr *)skb->data; |
1925 | (card->dev->type == ARPHRD_IEEE802_TR) ? | ||
1926 | ip_tr_mc_map(ip_hdr->daddr, tg_addr): | ||
1927 | ip_eth_mc_map(ip_hdr->daddr, tg_addr); | 1867 | ip_eth_mc_map(ip_hdr->daddr, tg_addr); |
1928 | break; | 1868 | break; |
1929 | default: | 1869 | default: |
@@ -1959,12 +1899,7 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card, | |||
1959 | tg_addr, "FAKELL", card->dev->addr_len); | 1899 | tg_addr, "FAKELL", card->dev->addr_len); |
1960 | } | 1900 | } |
1961 | 1901 | ||
1962 | #ifdef CONFIG_TR | 1902 | skb->protocol = eth_type_trans(skb, card->dev); |
1963 | if (card->dev->type == ARPHRD_IEEE802_TR) | ||
1964 | skb->protocol = tr_type_trans(skb, card->dev); | ||
1965 | else | ||
1966 | #endif | ||
1967 | skb->protocol = eth_type_trans(skb, card->dev); | ||
1968 | 1903 | ||
1969 | if (hdr->hdr.l3.ext_flags & | 1904 | if (hdr->hdr.l3.ext_flags & |
1970 | (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { | 1905 | (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { |
@@ -2138,7 +2073,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev, | |||
2138 | struct net_device *netdev; | 2073 | struct net_device *netdev; |
2139 | 2074 | ||
2140 | rcu_read_lock(); | 2075 | rcu_read_lock(); |
2141 | netdev = __vlan_find_dev_deep(dev, vid); | 2076 | netdev = __vlan_find_dev_deep(card->dev, vid); |
2142 | rcu_read_unlock(); | 2077 | rcu_read_unlock(); |
2143 | if (netdev == dev) { | 2078 | if (netdev == dev) { |
2144 | rc = QETH_VLAN_CARD; | 2079 | rc = QETH_VLAN_CARD; |
@@ -2883,13 +2818,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, | |||
2883 | hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; | 2818 | hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; |
2884 | memcpy(hdr->hdr.l3.dest_addr, pkey, 16); | 2819 | memcpy(hdr->hdr.l3.dest_addr, pkey, 16); |
2885 | } else { | 2820 | } else { |
2886 | /* passthrough */ | 2821 | if (!memcmp(skb->data + sizeof(struct qeth_hdr), |
2887 | if ((skb->dev->type == ARPHRD_IEEE802_TR) && | ||
2888 | !memcmp(skb->data + sizeof(struct qeth_hdr) + | ||
2889 | sizeof(__u16), skb->dev->broadcast, 6)) { | ||
2890 | hdr->hdr.l3.flags = QETH_CAST_BROADCAST | | ||
2891 | QETH_HDR_PASSTHRU; | ||
2892 | } else if (!memcmp(skb->data + sizeof(struct qeth_hdr), | ||
2893 | skb->dev->broadcast, 6)) { | 2822 | skb->dev->broadcast, 6)) { |
2894 | /* broadcast? */ | 2823 | /* broadcast? */ |
2895 | hdr->hdr.l3.flags = QETH_CAST_BROADCAST | | 2824 | hdr->hdr.l3.flags = QETH_CAST_BROADCAST | |
@@ -3031,10 +2960,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3031 | skb_pull(new_skb, ETH_HLEN); | 2960 | skb_pull(new_skb, ETH_HLEN); |
3032 | } else { | 2961 | } else { |
3033 | if (ipv == 4) { | 2962 | if (ipv == 4) { |
3034 | if (card->dev->type == ARPHRD_IEEE802_TR) | 2963 | skb_pull(new_skb, ETH_HLEN); |
3035 | skb_pull(new_skb, TR_HLEN); | ||
3036 | else | ||
3037 | skb_pull(new_skb, ETH_HLEN); | ||
3038 | } | 2964 | } |
3039 | 2965 | ||
3040 | if (ipv != 4 && vlan_tx_tag_present(new_skb)) { | 2966 | if (ipv != 4 && vlan_tx_tag_present(new_skb)) { |
@@ -3318,12 +3244,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) | |||
3318 | card->info.type == QETH_CARD_TYPE_OSX) { | 3244 | card->info.type == QETH_CARD_TYPE_OSX) { |
3319 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || | 3245 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || |
3320 | (card->info.link_type == QETH_LINK_TYPE_HSTR)) { | 3246 | (card->info.link_type == QETH_LINK_TYPE_HSTR)) { |
3321 | #ifdef CONFIG_TR | 3247 | pr_info("qeth_l3: ignoring TR device\n"); |
3322 | card->dev = alloc_trdev(0); | 3248 | return -ENODEV; |
3323 | #endif | ||
3324 | if (!card->dev) | ||
3325 | return -ENODEV; | ||
3326 | card->dev->netdev_ops = &qeth_l3_netdev_ops; | ||
3327 | } else { | 3249 | } else { |
3328 | card->dev = alloc_etherdev(0); | 3250 | card->dev = alloc_etherdev(0); |
3329 | if (!card->dev) | 3251 | if (!card->dev) |
@@ -3376,12 +3298,6 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev) | |||
3376 | qeth_l3_create_device_attributes(&gdev->dev); | 3298 | qeth_l3_create_device_attributes(&gdev->dev); |
3377 | card->options.layer2 = 0; | 3299 | card->options.layer2 = 0; |
3378 | card->info.hwtrap = 0; | 3300 | card->info.hwtrap = 0; |
3379 | card->discipline.start_poll = qeth_qdio_start_poll; | ||
3380 | card->discipline.input_handler = (qdio_handler_t *) | ||
3381 | qeth_qdio_input_handler; | ||
3382 | card->discipline.output_handler = (qdio_handler_t *) | ||
3383 | qeth_qdio_output_handler; | ||
3384 | card->discipline.recover = qeth_l3_recover; | ||
3385 | return 0; | 3301 | return 0; |
3386 | } | 3302 | } |
3387 | 3303 | ||
@@ -3656,8 +3572,12 @@ out: | |||
3656 | return rc; | 3572 | return rc; |
3657 | } | 3573 | } |
3658 | 3574 | ||
3659 | struct ccwgroup_driver qeth_l3_ccwgroup_driver = { | 3575 | struct qeth_discipline qeth_l3_discipline = { |
3660 | .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, | ||
3661 | .remove = qeth_l3_remove_device, | 3581 | .remove = qeth_l3_remove_device, |
3662 | .set_online = qeth_l3_set_online, | 3582 | .set_online = qeth_l3_set_online, |
3663 | .set_offline = qeth_l3_set_offline, | 3583 | .set_offline = qeth_l3_set_offline, |
@@ -3666,7 +3586,7 @@ struct ccwgroup_driver qeth_l3_ccwgroup_driver = { | |||
3666 | .thaw = qeth_l3_pm_resume, | 3586 | .thaw = qeth_l3_pm_resume, |
3667 | .restore = qeth_l3_pm_resume, | 3587 | .restore = qeth_l3_pm_resume, |
3668 | }; | 3588 | }; |
3669 | EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver); | 3589 | EXPORT_SYMBOL_GPL(qeth_l3_discipline); |
3670 | 3590 | ||
3671 | static int qeth_l3_ip_event(struct notifier_block *this, | 3591 | static int qeth_l3_ip_event(struct notifier_block *this, |
3672 | unsigned long event, void *ptr) | 3592 | unsigned long event, void *ptr) |
@@ -3680,9 +3600,9 @@ static int qeth_l3_ip_event(struct notifier_block *this, | |||
3680 | return NOTIFY_DONE; | 3600 | return NOTIFY_DONE; |
3681 | 3601 | ||
3682 | card = qeth_l3_get_card_from_dev(dev); | 3602 | card = qeth_l3_get_card_from_dev(dev); |
3683 | QETH_CARD_TEXT(card, 3, "ipevent"); | ||
3684 | if (!card) | 3603 | if (!card) |
3685 | return NOTIFY_DONE; | 3604 | return NOTIFY_DONE; |
3605 | QETH_CARD_TEXT(card, 3, "ipevent"); | ||
3686 | 3606 | ||
3687 | addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); | 3607 | addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); |
3688 | if (addr != NULL) { | 3608 | if (addr != NULL) { |
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index d979bb26522f..4cafedf950ad 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c | |||
@@ -175,116 +175,6 @@ out: | |||
175 | static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show, | 175 | static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show, |
176 | qeth_l3_dev_fake_broadcast_store); | 176 | qeth_l3_dev_fake_broadcast_store); |
177 | 177 | ||
178 | static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev, | ||
179 | struct device_attribute *attr, char *buf) | ||
180 | { | ||
181 | struct qeth_card *card = dev_get_drvdata(dev); | ||
182 | |||
183 | if (!card) | ||
184 | return -EINVAL; | ||
185 | |||
186 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | ||
187 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) | ||
188 | return sprintf(buf, "n/a\n"); | ||
189 | |||
190 | return sprintf(buf, "%s\n", (card->options.broadcast_mode == | ||
191 | QETH_TR_BROADCAST_ALLRINGS)? | ||
192 | "all rings":"local"); | ||
193 | } | ||
194 | |||
195 | static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev, | ||
196 | struct device_attribute *attr, const char *buf, size_t count) | ||
197 | { | ||
198 | struct qeth_card *card = dev_get_drvdata(dev); | ||
199 | char *tmp; | ||
200 | int rc = 0; | ||
201 | |||
202 | if (!card) | ||
203 | return -EINVAL; | ||
204 | |||
205 | mutex_lock(&card->conf_mutex); | ||
206 | if ((card->state != CARD_STATE_DOWN) && | ||
207 | (card->state != CARD_STATE_RECOVER)) { | ||
208 | rc = -EPERM; | ||
209 | goto out; | ||
210 | } | ||
211 | |||
212 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | ||
213 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { | ||
214 | rc = -EINVAL; | ||
215 | goto out; | ||
216 | } | ||
217 | |||
218 | tmp = strsep((char **) &buf, "\n"); | ||
219 | |||
220 | if (!strcmp(tmp, "local")) | ||
221 | card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL; | ||
222 | else if (!strcmp(tmp, "all_rings")) | ||
223 | card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; | ||
224 | else | ||
225 | rc = -EINVAL; | ||
226 | out: | ||
227 | mutex_unlock(&card->conf_mutex); | ||
228 | return rc ? rc : count; | ||
229 | } | ||
230 | |||
231 | static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show, | ||
232 | qeth_l3_dev_broadcast_mode_store); | ||
233 | |||
234 | static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev, | ||
235 | struct device_attribute *attr, char *buf) | ||
236 | { | ||
237 | struct qeth_card *card = dev_get_drvdata(dev); | ||
238 | |||
239 | if (!card) | ||
240 | return -EINVAL; | ||
241 | |||
242 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | ||
243 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) | ||
244 | return sprintf(buf, "n/a\n"); | ||
245 | |||
246 | return sprintf(buf, "%i\n", (card->options.macaddr_mode == | ||
247 | QETH_TR_MACADDR_CANONICAL)? 1:0); | ||
248 | } | ||
249 | |||
250 | static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, | ||
251 | struct device_attribute *attr, const char *buf, size_t count) | ||
252 | { | ||
253 | struct qeth_card *card = dev_get_drvdata(dev); | ||
254 | char *tmp; | ||
255 | int i, rc = 0; | ||
256 | |||
257 | if (!card) | ||
258 | return -EINVAL; | ||
259 | |||
260 | mutex_lock(&card->conf_mutex); | ||
261 | if ((card->state != CARD_STATE_DOWN) && | ||
262 | (card->state != CARD_STATE_RECOVER)) { | ||
263 | rc = -EPERM; | ||
264 | goto out; | ||
265 | } | ||
266 | |||
267 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | ||
268 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { | ||
269 | rc = -EINVAL; | ||
270 | goto out; | ||
271 | } | ||
272 | |||
273 | i = simple_strtoul(buf, &tmp, 16); | ||
274 | if ((i == 0) || (i == 1)) | ||
275 | card->options.macaddr_mode = i? | ||
276 | QETH_TR_MACADDR_CANONICAL : | ||
277 | QETH_TR_MACADDR_NONCANONICAL; | ||
278 | else | ||
279 | rc = -EINVAL; | ||
280 | out: | ||
281 | mutex_unlock(&card->conf_mutex); | ||
282 | return rc ? rc : count; | ||
283 | } | ||
284 | |||
285 | static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show, | ||
286 | qeth_l3_dev_canonical_macaddr_store); | ||
287 | |||
288 | static ssize_t qeth_l3_dev_sniffer_show(struct device *dev, | 178 | static ssize_t qeth_l3_dev_sniffer_show(struct device *dev, |
289 | struct device_attribute *attr, char *buf) | 179 | struct device_attribute *attr, char *buf) |
290 | { | 180 | { |
@@ -458,8 +348,6 @@ static struct attribute *qeth_l3_device_attrs[] = { | |||
458 | &dev_attr_route4.attr, | 348 | &dev_attr_route4.attr, |
459 | &dev_attr_route6.attr, | 349 | &dev_attr_route6.attr, |
460 | &dev_attr_fake_broadcast.attr, | 350 | &dev_attr_fake_broadcast.attr, |
461 | &dev_attr_broadcast_mode.attr, | ||
462 | &dev_attr_canonical_macaddr.attr, | ||
463 | &dev_attr_sniffer.attr, | 351 | &dev_attr_sniffer.attr, |
464 | &dev_attr_hsuid.attr, | 352 | &dev_attr_hsuid.attr, |
465 | NULL, | 353 | NULL, |